这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战
WebService学习
webService简介
webService接口,cxf框架,用xml配置暴露的接口,接口提供方可以用已实现序列化接口的对象来接收,当然,一般接口的数据结构没有那么简单,那我们也可以相对应的在我们要接收数据的对象里加List或者对象属性来实现。cxf框架会自动把xml数据转化为我们所需的对象,底层传输的实际上是通过http协议传输xml数据(可以写一个拦截器获取发送的xml文件)
说白了就是xml文档的生成、传递、解析的过程。客户端生成xml文件后通过网络传送给服务器,服务器解析xml,获取参数执行方法得到返回值,之后生成xml文件,再传输给客户端,客户端解析xml后显示数据。
xml传输数据的话一般是webSerivce,偏银行多一些;而Json则偏互联网多一些。暴露接口的话,我们可以写一个controller,用@RequestMapping("xxxx")来指定接口的调用地址;底层传输的都是json字符串,我们可以用String来接收,也可以用对象来接收(实现序列化接口),一般用的框架有阿里的fastjson跟springMvc自带的jackson
暴露webservice服务
场景一:Spring boot2.X
环境:Spring boot2.X
- 添加cxf依赖
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.2.5</version>
</dependency>
复制代码
- 在外放的Facade接口上添加@WebService注解,方法上添加@WebMethod注解
@WebService
public interface AuthServiceFacade {
@WebMethod
AuthResponse auth(AuthRequest request);
}
复制代码
- 实现类上添加注解@WebService注解
@Component
@Service
@WebService(targetNamespace = "http://webservice.company.com/",endpointInterface = "com.***.auth.service.facade.AuthServiceFacade")
public class BankCardSingleAuthServiceImpl extends AbstractAuthService
implements AuthServiceFacade {}
复制代码
- 设置WebServiceConfig
场景二:通过CommandLineRunner暴露
//SpringBoot启动后会自动加载并暴露服务,服务ip可以动态适配
@Configuration
@Order(1)//数字为初始化顺序
public class CxfConfig implements CommandLineRunner {
@Value("${url:localhost}")
private String url ;
@Override
public void run(String... args){
Service service = new Service();
Endpoint.publish("http://"+url+":8080/service", service);
}
}
复制代码
Wsdl文件
重要属性
重要标签的说明
· types - 数据类型(标签)定义的容器,里面使用schema定义了一些标签结构供message引用
· message - 通信消息的数据结构的抽象类型化定义。引用types中定义的标签
· operation - 对服务中所支持的操作的抽象描述,一个operation描述了一个访问入口的请求消息与响应消息对。
· portType - 对于某个访问入口点类型所支持的操作的抽象集合,这些操作可以由一个或多个服务访问点来支持。
· binding - 特定端口类型的具体协议和数据格式规范的绑定。
· service- 相关服务访问点的集合
· port - 定义为协议/数据格式绑定与具体Web访问地址组合的单个服务访问点。
常见错误
无法通过包wsdl文件以maven打包的方式生成
需要删除maven打包的targe再打包即可生成
@WebService注解的类中无法注入@Autowrite
这个问题让我很头痛,没想到是通过使用静态块去做的。
@WebService(endpointInterface = "***", serviceName = "***")
@Component
public class WebService implements IWebService {
@Autowired
private static ISecondService secondService;
// 这里使用静态,让 service 属于类
static {
//装载单个配置文件实例化ApplicationContext容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring\\dubbo.xml");
secondService = (ISecondService) ctx.getBean("secondService");
}
复制代码
soupUI能调试通但注册到别人服务中无法接收到请求,这个问题可能是因为两个服务之间格式不一样,我们可以在注册服务中再包一层,使用适配器设计模式处理这个问题。