Webservice非匿名訪問(用戶名密碼)

CXF Webservice非匿名訪問

關於這個非匿名訪問在網上找的不算多,自己也是多家融合,纔有點起色,在這裏記錄一下避免又忘了:

關於webservice咋寫的我就不多說了,網上一抓一大把,直接上有關cxf 非匿名訪問的代碼了哈

webservice公開的實現類

首頁是服務端的webservice上的註解哈,,注意這裏的serviceName (本人用的Spring+SpringMVC+Mybatis框架)

import javax.jws.WebService;

@Transactional
@Service
@WebService(endpointInterface = "com.sshome.ssmcxf.webservice.CompanyWebService", serviceName = "CompanyWebService")
public class CompanyWebServiceImpl implements CompanyWebService {
    ......
}

AuthInterceptor類 處理用戶名密碼

這裏是在客戶端直接自定義SOAP頭,然後到服務端的handler中拿到這個頭進行分析

package com.sshome.ssmcxf.webservice.impl;


import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Node;
public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

 private SAAJInInterceptor saa = new SAAJInInterceptor();

 public AuthInterceptor() {
      super(Phase.PRE_PROTOCOL);
      getAfter().add(SAAJInInterceptor.class.getName());
 }
 public void handleMessage(SoapMessage message) throws Fault {
     SOAPMessage mess = message.getContent(SOAPMessage.class);
      if (mess == null) {
       saa.handleMessage(message);
       mess = message.getContent(SOAPMessage.class);
      }
      try {
          SOAPHeader header = mess.getSOAPHeader();
          if (header != null) {
              Node userNameNode = header.getElementsByTagName("userName").item(0);
              Node passwordNode = header.getElementsByTagName("password").item(0);
              String userName = "", password = "";
              if(userNameNode != null && passwordNode != null){
                  userName = userNameNode.getTextContent();
                  password = passwordNode.getTextContent();
                  if (userName != null && !"".equals(userName ) && password != null && !"".equals(password )) {
                      if(userName.equals("admin") && password.equals("123456")){
                          System.out.println("認證成功!!!");
                      }else{
                          SOAPException soapExc = new SOAPException("認證錯誤");
                          throw new Fault(soapExc);
                      }
                  }else{
                      SOAPException soapExc = new SOAPException("認證錯誤");
                      throw new Fault(soapExc);
                  }
              }else{
                  SOAPException soapExc = new SOAPException("認證錯誤");
                  throw new Fault(soapExc);
              }
          } else {
                  SOAPException soapExc = new SOAPException("認證錯誤");
                  throw new Fault(soapExc);
          }
      } catch (SOAPException e) {
          e.printStackTrace();
      }
    }
}

這裏寫圖片描述

applicationContext-webservice.xml

webservice配置 重要等級五顆星哦,注意他們的對應關係,這個類肯定是要在web.xml配置的我就不多說了哈

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

    <!-- 這就是上面寫的類的地址啦 -->
    <bean id="companyWebService" class="com.sshome.ssmcxf.webservice.impl.CompanyWebServiceImpl"/>
    <bean id="inInterceptor" class="com.sshome.ssmcxf.webservice.impl.AuthInterceptor"/>

    <!--    address的名稱就是訪問的WebServicename -->
    <jaxws:server id="companyService" serviceClass="com.sshome.ssmcxf.webservice.CompanyWebService" address="/companyWebService">
        <jaxws:serviceBean>
            <!--  要暴露的 bean 的引用 -->
            <ref bean="companyWebService"/>
        </jaxws:serviceBean>
        <jaxws:inInterceptors>
            <!-- 攔截處理用戶名密碼 -->
            <ref bean="inInterceptor"/>
        </jaxws:inInterceptors>
    </jaxws:server>

</beans>
    ......
}

OK 服務端搞定啦,接下來就是偶們滴客戶端啦:

客戶端的AuthorityHeaderInterceptor類,配置服務器端Head信息的用戶密碼

package com.spring.test;

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

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;

public class AuthorityHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage>{  
    private AuthorityParameter authorityParameter;
    public AuthorityHeaderInterceptor(AuthorityParameter authorityParameter) {  
        super(Phase.PREPARE_SEND);  
        this.authorityParameter = authorityParameter;
    }   

    public void handleMessage(SoapMessage msg) throws Fault {    
        List<Header> headers = msg.getHeaders();  
        //創建Document對象  
        Document doc = DOMUtils.createDocument();  

        //配置服務器端Head信息的用戶密碼  
        Element eleId= doc.createElement(this.authorityParameter.getUserNameKey());  
        eleId.setTextContent(this.authorityParameter.getUserNameValue());  
        Element elePass = doc.createElement(this.authorityParameter.getPasswordKey());  
        elePass.setTextContent(this.authorityParameter.getPasswordValue());   
        /** 
         * 也可以先創建一個父節點,則生成的XML文檔 ,我們這裏是直接使用用戶名和密碼
         * <authHeader> 
         *      <userId>admin</userId> 
         *      <userPass>123456</userPass> 
         * </authHeader> 
         */  
        headers.add(new Header(new QName(""), eleId));  
        headers.add(new Header(new QName(""), elePass)); 
    }   
}  

參數類

package com.spring.test;

public class AuthorityParameter {
package com.spring.test;

public class AuthorityParameter {

    /**
    * 用戶名及密碼的字段、名稱
    */
    private String userNameKey;
    private String userNameValue;
    private String passwordKey;
    private String passwordValue;


    public String getUserNameKey() {
        return userNameKey;
    }

    public void setUserNameKey(String userNameKey) {
        this.userNameKey = userNameKey;
    }

    public String getUserNameValue() {
        return userNameValue;
    }

    public void setUserNameValue(String userNameValue) {
        this.userNameValue = userNameValue;
    }

    public String getPasswordKey() {
        return passwordKey;
    }

    public void setPasswordKey(String passwordKey) {
        this.passwordKey = passwordKey;
    }

    public String getPasswordValue() {
        return passwordValue;
    }

    public void setPasswordValue(String passwordValue) {
        this.passwordValue = passwordValue;
    }

    public AuthorityParameter() {
    super();
    }

    /**  
    * AuthorityParameter
    * @param userNameKey 用戶名字段
    * @param userNameValue 用戶名值
    * @param passwordKey 密碼字段
    * @param passwordValue 密碼值
    */
    public AuthorityParameter(String userNameKey, String userNameValue, String passwordKey, String passwordValue) {
    super();
    this.userNameKey = userNameKey;
    this.userNameValue = userNameValue;
    this.passwordKey = passwordKey;
    this.passwordValue = passwordValue;
    }

}

然後肯定就是客戶端與服務端的連接與處理了

客戶端與服務端的連接方式有很多中,個人覺得這種連接方式比較便捷,至少對於我的項目來說是的,具體的各位自己參考

package com.spring.test;

import javax.xml.namespace.QName;

import net.sf.json.JSONObject;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONArray;
@Controller
@RequestMapping(value = "/demo", produces = { "text/json;charset=UTF-8" })
public class Demo {
    @RequestMapping("/chart")
    @ResponseBody
    public String efficiency(){
        //創建連接
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        Client client = dcf.createClient("http://192.168.73.156:8080/Company_Service/companyWebService?wsdl");
        AuthorityParameter param = new AuthorityParameter("userName", "admin", "password", "123456");
        client.getOutInterceptors().add(new AuthorityHeaderInterceptor(param)); 
        client.getOutInterceptors().add(new LoggingOutInterceptor()); 
        HTTPClientPolicy policy = ((HTTPConduit) client.getConduit()).getClient();
        policy.setConnectionTimeout(30000);
        policy.setReceiveTimeout(180000);
        try{
            //連接方法的參數
            String obj1 = "{\"TIME\":\"2018/04/20\",\"NUM\":\"8\"}";
            //"http://webservice.ssmcxf.sshome.com/"爲webservice的命名空間,enterChart是我的方法名
            Object[] objects = client.invoke(new QName("http://webservice.ssmcxf.sshome.com/", "enterChart"), new Object[]{obj1});  
            String result = objects[0].toString();// 返回值 
            System.out.println(result);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章