springboot2.1.1集成webService

最近在做接口时,需求是提供restful api和webService两种方式共享数据。对于webService方式,大多数同学还是很陌生的,我在做的过程中也踩了一些坑,现记录下来,分享给大家。

pom.xml

<dependency> 
     <groupId>org.apache.cxf</groupId> 
     <artifactId>cxf-spring-boot-starter-jaxws</artifactId>         
     <version>3.2.9</version> 
</dependency>

 

springboot是2.1.1版本

项目结构:服务端和客户端

服务端代码:

import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.qm.boot.web.webService.server.Interceptor.AuthInterceptor;
import com.qm.boot.web.webService.server.service.DataCenterService;

import javax.xml.ws.Endpoint;

@Configuration
public class CxfConfig {
    
    @Autowired
    private DataCenterService DataCenterServiceImpl;
    /**
     * 为了不被springSecurity拦截,自定义暴露的路径
     * 默认为/services/**
     */
    @Bean
    public ServletRegistrationBean<CXFServlet> myServlet(){
        ServletRegistrationBean<CXFServlet> registrationBean =new ServletRegistrationBean<CXFServlet>(new CXFServlet(),"/webService/*");
        return registrationBean;
    }

    @Bean(name = Bus.DEFAULT_BUS_ID)
    public SpringBus springBus() {
        return new SpringBus();
    }

    //终端路径
    @Bean
    public Endpoint endpoint() {
        EndpointImpl endpoint = new EndpointImpl(springBus(), DataCenterServiceImpl);
        endpoint.getInInterceptors().add(new AuthInterceptor());//添加校验拦截器
        endpoint.publish("/dataShare");
        return endpoint;
    }
}
 1 import org.apache.cxf.binding.soap.SoapHeader;
 2 import org.apache.cxf.binding.soap.SoapMessage;
 3 import org.apache.cxf.common.util.StringUtils;
 4 import org.apache.cxf.headers.Header;
 5 import org.apache.cxf.interceptor.Fault;
 6 import org.apache.cxf.phase.AbstractPhaseInterceptor;
 7 import org.apache.cxf.phase.Phase;
 8 import org.slf4j.Logger;
 9 import org.slf4j.LoggerFactory;
10 import org.w3c.dom.Element;
11 import org.w3c.dom.NodeList;
12 
13 import javax.xml.soap.SOAPException;
14 import java.util.List;
15 /**
16  * 自定义拦截器
17  */
18 public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
19     Logger logger = LoggerFactory.getLogger(this.getClass());
20     private static final String USERNAME="root";
21     private static final String PASSWORD="admin";
22 
23     public AuthInterceptor() {
24         //定义在哪个阶段进行拦截
25         super(Phase.PRE_PROTOCOL);
26     }
27 
28     @Override
29     public void handleMessage(SoapMessage soapMessage) throws Fault {
30         List<Header> headers = null;
31         String username=null;
32         String password=null;
33         try {
34            headers = soapMessage.getHeaders();
35         } catch (Exception e) {
36             logger.error("getSOAPHeader error: {}",e.getMessage(),e);
37         }
38 
39         if (headers == null) {
40             throw new Fault(new IllegalArgumentException("找不到Header,无法验证用户信息"));
41         }
42         //获取用户名,密码
43         for (Header header : headers) {
44             SoapHeader soapHeader = (SoapHeader) header;
45             Element e = (Element) soapHeader.getObject();
46             NodeList usernameNode = e.getElementsByTagName("username");
47             NodeList pwdNode = e.getElementsByTagName("password");
48              username=usernameNode.item(0).getTextContent();
49              password=pwdNode.item(0).getTextContent();
50             if( StringUtils.isEmpty(username)||StringUtils.isEmpty(password)){
51                 throw new Fault(new IllegalArgumentException("用户信息为空"));
52             }
53         }
54         //校验用户名密码
55         if(!(username.equals(USERNAME) && password.equals(PASSWORD))){
56             SOAPException soapExc = new SOAPException("用户认证信息错误");
57             logger.debug("用户认证信息错误");
58             throw new Fault(soapExc);
59         }
60 
61     }
62 
63 }
 1 import java.io.UnsupportedEncodingException;
 2 
 3 import javax.jws.WebMethod;
 4 import javax.jws.WebParam;
 5 import javax.jws.WebService;
 6 
 7 @WebService
 8 public interface DataCenterService {
 9     @WebMethod
10     public String dataShare(@WebParam(name = "code")String code,@WebParam(name = "type")String type,@WebParam(name = "count")Integer count, @WebParam(name = "currentPage")Integer currentPage,@WebParam(name = "startTime")String startTime,@WebParam(name = "userName")String userName, @WebParam(name = "sign")String sign)throws UnsupportedEncodingException;
11 }
import java.io.UnsupportedEncodingException;

import javax.jws.WebService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.qm.boot.web.api.component.DataShareComponent;
import com.qm.boot.web.webService.server.service.DataCenterService;

/**
 * targetNamespace:按照endpointInterface反写,很关键
 */
@Service
@WebService(name = "dataShare" ,targetNamespace ="http://service.server.webService.web.boot.qm.com/" ,endpointInterface = "com.qm.boot.web.webService.server.service.DataCenterService")
public class DataCenterServiceImpl implements DataCenterService {
    @Autowired
    private DataShareComponent dataShareComponent;
    
    @Override
    public String dataShare(String code, String type, Integer count, Integer currentPage, String startTime, String userName, String sign) throws UnsupportedEncodingException {
        return JSON.toJSONString(dataShareComponent.dataShare(code, type, count, currentPage, startTime, userName, sign));
    }
}

 

 客户端代码:

 1 import org.apache.cxf.binding.soap.SoapMessage;
 2 import org.apache.cxf.headers.Header;
 3 import org.apache.cxf.helpers.DOMUtils;
 4 import org.apache.cxf.interceptor.Fault;
 5 import org.apache.cxf.phase.AbstractPhaseInterceptor;
 6 import org.apache.cxf.phase.Phase;
 7 import org.w3c.dom.Document;
 8 import org.w3c.dom.Element;
 9 
10 import javax.xml.namespace.QName;
11 import java.util.List;
12 /**
13  * 自定义拦截器验证用户名密码
14  */
15 public class LoginInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
16     private String username="root";
17     private String password="admin";
18     public LoginInterceptor(String username, String password) {
19         //设置在发送请求前阶段进行拦截
20         super(Phase.PREPARE_SEND);
21         this.username=username;
22         this.password=password;
23     }
24 
25     @Override
26     public void handleMessage(SoapMessage soapMessage) throws Fault {
27         List<Header> headers = soapMessage.getHeaders();
28         Document doc = DOMUtils.createDocument();
29         Element auth = doc.createElementNS("http://service.server.webService.web.boot.qm.com/","SecurityHeader");
30         Element UserName = doc.createElement("username");
31         Element UserPass = doc.createElement("password");
32 
33         UserName.setTextContent(username);
34         UserPass.setTextContent(password);
35 
36         auth.appendChild(UserName);
37         auth.appendChild(UserPass);
38 
39         headers.add(0, new Header(new QName("SecurityHeader"),auth));
40     }
41 }
 1 import com.alibaba.fastjson.JSON;
 2 import com.alibaba.fastjson.JSONObject;
 3 import com.qm.boot.web.webService.client.interceptor.LoginInterceptor;
 4 
 5 import org.apache.cxf.endpoint.Client;
 6 import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
 7 //客户端测试demo
 8 public class CxfClient {
 9     //webService接口地址
10     private static String address = "http://localhost:8080/services/test?wsdl";
11     
12     
13     public static void main(String[] args) {
14         run();
15     }
16     
17       /**
18      * 动态调用方式
19      */
20     public static void run() {
21       
22         JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();  // 创建动态客户端
23         Client client = dcf.createClient(address);
24         
25         client.getOutInterceptors().add(new LoginInterceptor("root","admin"));// 需要密码的情况需要加上用户名和密码
26         Object[] objects = new Object[0];
27         try {
28              // invoke("方法名",参数1,参数2,参数3....);
29              objects = client.invoke("dataShare", "1","1",100,1,"","1","lXIh6PzSVPIyG6qMD");
30             System.out.println("返回数据:" +  JSONObject.parse(JSON.toJSONString(objects[0])));
31         } catch (Exception e) {
32             System.out.println(e.getMessage());
33             //e.printStackTrace();
34         }
35     }
36 }

如果项目集成了springSecurity,切记一定要排除对webService地址的拦截,不然客户端会请求失败

启动项目后,访问webService地址,可以看到发布成功如下:

 

 客户端调用成功:

 

转载于:https://www.cnblogs.com/xphhh/p/11237653.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值