CXF WebService 授权&动态调用

SpringBoot WebService 源代码:https://gitee.com/VipSoft/VipWebService

SpringBoot WebService 及 注意项: https://www.cnblogs.com/vipsoft/p/14993568.html

服务端添加拦截器

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import java.util.List;
import org.apache.cxf.binding.soap.SoapHeader;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
import javax.xml.soap.SOAPException;

@Component
public class WsAuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
    private static final String USERNAME = "root";
    private static final String PASSWORD = "admin";

    public WsAuthInterceptor() {
        // 定义在哪个阶段进行拦截
        super(Phase.PRE_PROTOCOL);
    }

    @Override
    public void handleMessage(SoapMessage soapMessage) throws Fault {
        List<Header> headers = soapMessage.getHeaders();
        String username = null;
        String password = null;
        if (headers == null || headers.isEmpty()) {
            throw new Fault(new IllegalArgumentException("找不到Header,无法验证用户信息"));
        }
        // 获取用户名,密码
        for (Header header : headers) {
            SoapHeader soapHeader = (SoapHeader) header;
            Element e = (Element) soapHeader.getObject();
            username = e.getAttribute("username");
            password = e.getAttribute("password");
            if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
                throw new Fault(new IllegalArgumentException("用户信息为空"));
            }
        }
        // 校验用户名密码
        if (!(USERNAME.equals(username) && PASSWORD.equals(password))) {
            SOAPException soapExc = new SOAPException("认证失败");
            System.err.println("用户认证信息错误");
            throw new Fault(soapExc);
        }
    }
}
 @Bean
    public Endpoint endpoint() {
        EndpointImpl endpoint = new EndpointImpl(springBus(), demoService()); //绑定要发布的服务
        endpoint.publish("/api"); // 暴露webService api,用在资源访问
        endpoint.getInInterceptors().add(wsAuthInterceptor);
        return endpoint;
    }

--------

客户端调用

SOAP UI 

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.his.iron.com">
   <soapenv:Header>
       <Author username="root" password="admin"></Author>
    </soapenv:Header> 
   <soapenv:Body>
      <ser:sayHello>
         <!--Optional:-->
         <arg>Test</arg>
      </ser:sayHello>
   </soapenv:Body>
</soapenv:Envelope>

 

WebService 动态调用

@Override
public String soapDynamicTest(String ip) {

    try{
      //创建动态客户端
      JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
      //        Client client = factory.createClient("http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx?wsdl");
      Client client = factory.createClient("http://192.168.1.216:9090/ws/api?wsdl");
      // 需要密码的情况需要加上用户名和密码
      //client.getOutInterceptors().add(new ClientAuthInterceptor("USER_NAME","PASS_WORD"));
      // 拦截器的方式
      client.getOutInterceptors().add(new ClientCheckInterceptor());

      HTTPConduit conduit = (HTTPConduit) client.getConduit();
      HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
      httpClientPolicy.setConnectionTimeout(2000);  //连接超时
      httpClientPolicy.setAllowChunking(false);    //取消块编码
      httpClientPolicy.setReceiveTimeout(120000);     //响应超时
      conduit.setClient(httpClientPolicy);

      //region Entity to xml
      
      // 假设你有一个 JSON 对象,这里我们简化为一个 Java 对象  
      MyObject myObject = new MyObject(); // 这个类应该与你的 JSON 结构对应  
      myObject.setField1("value1");  
      myObject.setField2("value2");  

      // 3. 将 Java 对象转换为 XML  
      JAXBContext jaxbContext = JAXBContext.newInstance(MyObject.class);  
      Marshaller marshaller = jaxbContext.createMarshaller();  
      StringWriter sw = new StringWriter();  
      marshaller.marshal(myObject, sw);  
      String xml = sw.toString();  

      //endregion


      Object[] objects = new Object[0];
      // invoke("方法名",参数1,参数2,参数3....);
      //            objects = client.invoke("getCountryCityByIp", ip);
      objects = client.invoke("sayHello", ip);
      System.out.println("返回数据:" + objects[0]);
      //            return ((ArrayOfString) objects[0]).getString().toString();
      return objects[0].toString();
    }catch (Exception e){
      e.printStackTrace();
    }
    return "";
}


ClientCheckInterceptor.java
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.namespace.QName;
import java.util.List;

public class ClientAuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
    private static final String USERNAME = "root";
    private static final String PASSWORD = "admin";
    public ClientCheckInterceptor() {
        super(Phase.PREPARE_SEND);
    }
    @Override
    public void handleMessage(SoapMessage message) throws Fault {
        List<Header> headers = message.getHeaders();
        Document document = DOMUtils.createDocument();
        Element authorEle = document.createElement("author");
        authorEle.setAttribute("username", USERNAME);
        authorEle.setAttribute("password", PASSWORD);
        headers.add(new Header(new QName(""), authorEle));
    }
}

 

posted @ 2021-07-10 18:24  VipSoft  阅读(220)  评论(0编辑  收藏  举报