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);
    }
}

猜你喜欢

转载自blog.csdn.net/notHavaBug/article/details/80491350
今日推荐