通常我们在开发中需要给别人提供webservice服务接口供别人使用,本文章主要基于cxf实现webservice服务
我们先写一个webservice接口类如下:
1 import java.util.List;
2 import javax.jws.WebMethod;
3 import javax.jws.WebParam;
4 import javax.jws.WebService;
5 import javax.xml.ws.Holder;
6 import javax.xml.ws.RequestWrapper;
7 import javax.xml.ws.ResponseWrapper;
8
9 /**
11 * @date:2020年10月14日
12 * @describe:基于soap协议(http+xml)的服务,name:定义Port名称,targetNamespace:命名空间
13 */
14 @WebService(name = "Me", targetNamespace = "http://bodhi.xxl.xh/xxx/service/")
15 public interface Me {
16
17 /**
19 * @date:2020年10月14日
20 * @describe
21 */
22 @WebMethod
23 public void syncUser(@WebParam(name = "str", targetNamespace = "") String str);
28 }
接着,写webservice的实现类:
1 import java.util.List;
2 import javax.xml.ws.Holder;
3
4 /**
6 * @date :2020年10月14日
7 * @param : MeImpl.java
8 * @return :MeImpl
9 * @description:webservice接口实现类
10 */
11 @javax.jws.WebService(endpointInterface = "xxx.bodhi.server.Me", targetNamespace = "http://bodhi.xxl.xh/xxx/service/", serviceName = "MeService", portName = "me")
12 public class MeImpl implements Me{
13
14 public void syncUser(String str) {
16 //do something
17 //在这个方法里面我们就可以做自己业务相关的操作,有时候我们需要注入其他的servcie进行后续操作,
18 //需要注意的是注入的时候不能直接通过@Autowired注解进行注入,这样注入的话,注入的service或者dao层的bean是空
19 //因为此时业务层 Bean 使用的 Spring 容器和调用 WebService 服务中使用的不是同一个 Spring 容器. 所以获取到的bean为空
20 //若要注入其他的service或者dao,可以通过配置类进行注入
21 }
22 }
接着。我们写配置类:
1 import org.apache.cxf.Bus;
2 import org.apache.cxf.bus.spring.SpringBus;
3 import org.apache.cxf.jaxws.EndpointImpl;
4 import org.apache.cxf.transport.servlet.CXFServlet;
5 import org.springframework.beans.factory.annotation.Autowired;
6 import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
7 import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer;
8 import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
9 import org.springframework.boot.web.servlet.ServletRegistrationBean;
10 import org.springframework.context.annotation.Bean;
11 import org.springframework.context.annotation.Configuration;
15 import java.util.List;
16 import javax.xml.ws.Endpoint;
17 /**
19 * @date :2020年10月14日
20 * @param : CxfConfig.java
21 * @return :CxfConfig
22 * @description: webservice配置类
23 */
24 @Configuration
25 public class CxfConfig {
26
27 @Bean
28 public ServletRegistrationBean dispatcherServlet() {
29 return new ServletRegistrationBean(new CXFServlet(),"/xxx/*");
30 }
31
32 @Bean(name = Bus.DEFAULT_BUS_ID)
33 public SpringBus springBus() {
34 return new SpringBus();
35 }
36
37 @Bean
38 public Me meService() {
39 return new MeImpl();
40 }
41
42 @Bean
43 public Endpoint endpoint() {
44 EndpointImpl endpoint = new EndpointImpl(springBus(), meService());
45 endpoint.publish("/service");//指定访问的接口名称,也可以配置起来
46 return endpoint;
47 }
48
49 @Bean
50 public EmbeddedServletContainerFactory servletContainer() {
51 TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
52 factory.addConnectorCustomizers(
53 (TomcatConnectorCustomizer) connector -> connector.setProperty("sendReasonPhrase", "true"));
54 return factory;
55 }
56
57 @Bean//我们可以在这儿进行我们自己的service注入,然后再webservice接口实现类中就可以通过@Autiowd注解进行注入了
58 public XXXService xxService() {
59 return new xxxServiceImpl();
60 }
61
62 }
访问路径为原先的springboot项目访问的ip+端口/xxxi/service?wsdl
以上就是springboot集成webservice的全部
这样有个弊端就是无法做到适配,在实际开发中可能很多业务组需要这样的接口去实现自己的逻辑,如果每个项目组为了自己不同的逻辑去再重复实现一遍又显得很臃肿,所以我们进行公共模块提取,接下来我们进行改造
首先改造接口实现类,修改后如下:
1 public void syncUser(String str,) {
6 for(Interceptor data :interceptor){
7 data.save(str);//此处可以加入返回值用于校验数据是否保存成功
9 }
10 }
11
12 public static List<Interceptor> interceptor;
13 public static interface Interceptor{
14 boolean save(String str);
15 }
然后我们在配置类里面进行注入,用于暴露给外部服务,加入以下代码:
1 @Autowired(required = false)
2 public void setSecureUFileInterceptors(List<Interceptor> interceptor){
3 MeImpl.interceptor = interceptor;
4 }
这样,我们就可以把以上几个文件打成jar包,如果有别的项目组用到引用这个jar包实现相应的接口即可
最后,我们看看如果调用jar包接口
1 /**
3 * @date :2020年10月14日
4 * @param : SaveData.java
5 * @return :SaveData
6 * @description: 使用demo,实现Interceptor接口即可,返回true,成功,false:失败
7 */
8 @Component
9 public class SaveData implements Interceptor{
10
11 @Override
12 public boolean save(String str) {
13 //do something
14 return true;
15 }
16
17 }
这样,就实现的代码复用的效果,以后使用起来也比较方便,如果有需要,可以借鉴,如果有用到相关jar包,可以留言索要