1.什么是webservice?
webservice是一种远程资源调用技术,它的实现方式主要分为两种,
第一种是jaxws方式,它是面向方法的,它的数据类型是xml是基于soap实现传输;
第二种是jaxrs方式,它是面向资源的,它的数据类型是xml或json是基于http协议实现传输。
2.jaxws简单应用
服务端:
第一步:创建一个简单的web项目,略
第二步:添加webService的依赖jar包,配置web.xml
<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>3.0.1</version> </dependency> 注:版本需与springboot对应 否则启动就会报错 在https://mvnrepository.com/artifact/org.apache.cxf/cxf-spring-boot-starter-jaxws查找到jaxws的各种版本,进入之后可以看到对应的springboot版本
问题详情: Description: Parameter 1 of constructor in org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration required a bean of type ‘org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath’ that could not be found. The following candidates were found but could not be injected: - Bean method ‘dispatcherServletRegistration’ in ‘DispatcherServletAutoConfiguration.DispatcherServletRegistrationConfiguration’ not loaded because DispatcherServlet Registration found non dispatcher servlet dispatcherServlet Action: Consider revisiting the entries above or defining a bean of type ‘org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath’ in your configuration. Process finished with exit code 1
启动报错(版本问题)
第三步:编写代码
1 import com.test.demo.service.IDataReceiverService; 2 import org.apache.cxf.Bus; 3 import org.apache.cxf.jaxws.EndpointImpl; 4 import org.springframework.beans.factory.annotation.Autowired; 5 import org.springframework.context.annotation.Bean; 6 import org.springframework.context.annotation.Configuration; 7 8 import javax.xml.ws.Endpoint; 9 10 /** 11 * 〈cxf配置〉 12 * 默认:services 13 * http://127.0.0.1:6689/services/receiveData 14 * cxf-path配置路径: 15 * http://127.0.0.1:6689/soap/receiveData 16 */ 17 @Configuration 18 public class CxfConfig { 19 20 @Autowired 21 private Bus bus; 22 23 @Autowired 24 private IDataReceiverService dataReceiverService; 25 26 27 /** 28 * 数据站点服务(总入口) 29 * 30 * @return 31 */ 32 @Bean 33 public Endpoint getReceiveData() { 34 EndpointImpl endpoint = new EndpointImpl(bus, dataReceiverService); 35 endpoint.publish("/receiveData"); 36 return endpoint; 37 } 38 39 }
CxfConfig
1 package com.test.demo.service; 2 3 4 import com.test.demo.entity.ReceiveMsg; 5 6 import javax.jws.WebMethod; 7 import javax.jws.WebParam; 8 import javax.jws.WebService; 9 10 /** 11 * 接收数据处理服务类 12 * 13 * @Author: zhangt 14 * @Date: 2021/9/11 11:46 15 */ 16 17 @WebService 18 public interface IDataReceiverService { 19 20 21 /** 22 * 接收数据接口 23 * 24 * @param receiveMsg 数据 25 * @return 26 */ 27 @WebMethod 28 String getReceiveMsg(@WebParam(name = "ROOT") ReceiveMsg receiveMsg); 29 30 }
service
1 package com.test.demo.service.impl; 2 3 import cn.hutool.core.collection.CollUtil; 4 import cn.hutool.core.convert.Convert; 5 import com.test.demo.entity.ReceiveMsg; 6 import com.test.demo.entity.ResultMsg; 7 import com.test.demo.entity.UploadData; 8 import com.test.demo.service.IDataReceiverService; 9 import com.test.demo.util.ReceiveMsgUtil; 10 import lombok.extern.slf4j.Slf4j; 11 import org.dom4j.DocumentException; 12 import org.springframework.stereotype.Component; 13 14 import javax.jws.WebService; 15 import java.util.List; 16 import java.util.Map; 17 18 @WebService(serviceName = "receiverService", // 与接口中指定的name一致 19 targetNamespace = "http://service.demo.test.com", // 与接口中的命名空间一致,一般是接口的包名倒序排 20 endpointInterface = "com.test.demo.service.IDataReceiverService"// 接口地址 21 ) 22 @Slf4j 23 @Component 24 public class DataReceiverServiceImpl implements IDataReceiverService { 25 26 /** 27 * 接收数据接口 28 * 29 * @param receiveMsg 数据 30 * @return 31 */ 32 @Override 33 public String getReceiveMsg(ReceiveMsg receiveMsg) { 34 35 //解析报文,转化为需要写成文件的数据 36 UploadData uploadData = new UploadData(); 37 String dataId = receiveMsg.getDATAID(); 38 uploadData.setDataId(dataId); 39 //是否加密 (1 表示业务数据为密文传输,0 表示明文) 40 int sec = Convert.toInt(receiveMsg.getSEC()); 41 uploadData.setHavePwd(sec); 42 43 //数据为明文时 44 if (1 == sec) { 45 //解码业务报文 46 try { 47 //获取解密后的业务数据 48 String data = ReceiveMsgUtil.decodeStr(receiveMsg.getBUSINESSCONTENT()); 49 List<Map<String, Object>> list = ReceiveMsgUtil.xmlToList(data); 50 log.info("数据为list:{}", list); 51 uploadData.setBusinessData(list); 52 if (CollUtil.isEmpty(list)) { 53 return ResultMsg.getMessage(ResultMsg.BUSINESS_DATA_ANALYZE_ERROR); 54 } 55 } catch (DocumentException e) { 56 log.info("xml数据格式不正确!", e); 57 return ResultMsg.getMessage(ResultMsg.XML_ERROR); 58 } catch (Exception e) { 59 log.info("base64解码错!", e); 60 return ResultMsg.getMessage(ResultMsg.BASE64_ERROR); 61 } 62 } 63 64 return ResultMsg.getMessage(ResultMsg.SUCCESS); 65 // return uploadData.getReplyData(); 66 } 67 68 }
serviceImpl
1 server: 2 port: 6689 3 spring: 4 application: 5 name: cxfDemo 6 # profiles: 7 # active: dev 8 cxf: 9 path: /soap #默认services
yml
第四步:启动项目,查看wsdl说明书
这里面的路径注意cxf在web中的配置:
参数说明:
@WebService:在接口上申明,表示该接口是一个webService服务;
@WebMethod:在接口方法上声明,表示该方法是一个webService服务方法;
@WebService(endpointInterface=”cn.linc.cxf.interfaces.ServiceUI”,serviceName=”userService”):在该接口实现类定义;
endpointInterface:表示接口服务终端接口名;
serviceName:服务名称;
wsdl解读:有五个节点:服务视图,服务协议和参数的描述,服务实现,参数描述,参数类型描述。
调用展示:
原理解析:
可以分为三个角色:服务提供者,服务消费者,服务注册中心uddi
首先由服务提供者发布服务并且在注册中心uddi进行注册
然后由服务消费者订阅服务,在注册中心uddi上查询到符合条件的服务
服务注册中心返回服务条件服务的描述文件给服务订阅者
订阅者根据描述文件进行服务端的服务调用,并返回数据。
工具:
加解密:https://tool.oschina.net/encrypt
soapUI:https://www.soapui.org/downloads/soapui/
参考:
https://blog.csdn.net/qiaodaima0/article/details/100765613
https://www.cnblogs.com/xiechenglin/p/10500558.html
https://www.cnblogs.com/shuaijie/articles/5913750.html