JAVA Webservice服务发布、调用示例,WSS认证调用实现

SpringBoot发布Webservice服务

SpringBoot发布Webservice其实就是通过Webservice注解将JAVA的Class类暴露为Webservice服务。

发布服务所需依赖

// webservice发布所需依赖
<dependency>
	<groupId>org.apache.cxf</groupId>
	<artifactId>cxf-rt-frontend-jaxws</artifactId>
	<version>3.1.5</version>
</dependency>
<dependency>
	<groupId>org.apache.cxf</groupId>
	<artifactId>cxf-rt-transports-http-jetty</artifactId>
	<version>3.1.5</version>
</dependency>

发布Webservice服务只需要这两个依赖就好了,JDK使用的是1.8。依赖引入后就开始看代码吧!

编写待暴露的服务类

在编写代码之前需要了解Webservice相关注解的使用【自行百度了解】。这里就不做说明了。直接上代码!

import org.apache.cxf.annotations.WSDLDocumentation;
import org.apache.cxf.annotations.WSDLDocumentationCollection;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.ws.Endpoint;

/**
 * @Author: zp
 * @Description: TODO
 * @Date: 2021/6/24 14:17
 * @Version: 1.0
 */
@WebService(serviceName="EWebService",targetNamespace="http://com.zpg.fun")
@SOAPBinding(style = SOAPBinding.Style.RPC)
//wsdl xml文档说明
@WSDLDocumentation(value = "此服务为SpringBoot将JAVA Class注解为WebService服务,服务消费时可按照JSON和XML的数据格式进行不同的服务选择。此服务仅作为服务示例,无服务的具体实现。",
        placement = WSDLDocumentation.Placement.TOP)
public class EWebService {

    @WebMethod(operationName="RequestDataByJson")
    @WebResult(name="jsonReturn")
    @WSDLDocumentationCollection(
        {
            @WSDLDocumentation("RequestDataByJson接收json格式的入参进行服务的消费"),
            @WSDLDocumentation(value = "入参须遵循json数据格式进行服务的消费",
                    placement = WSDLDocumentation.Placement.INPUT_MESSAGE),
            @WSDLDocumentation(value = "RequestDataByJson服务响应内容",
                    placement = WSDLDocumentation.Placement.OUTPUT_MESSAGE)
        }
    )
    public Object RequestDataByJson(@WebParam(name="jsonReqParam")String jsonReqParam,@WebParam(name="param2")String param2){
        System.out.println("===========RequestDataByJson============="+param2);
        return RequestOther(jsonReqParam);
    }

    @WebMethod(operationName="RequestDataByXml")
    @WebResult(name="xmlReturn")
    @WSDLDocumentationCollection(
        {
            @WSDLDocumentation("RequestDataByXml接收xml格式的入参进行服务的消费"),
            @WSDLDocumentation(value = "入参须遵循xml数据格式进行服务的消费",
                    placement = WSDLDocumentation.Placement.INPUT_MESSAGE),
            @WSDLDocumentation(value = "RequestDataByXml服务响应内容",
                    placement = WSDLDocumentation.Placement.OUTPUT_MESSAGE)
        }
    )
    public Object RequestDataByXml(@WebParam(name="xmlReqParam")String xmlReqParam){
        System.out.println("===========RequestDataByXml=============");
        return  RequestOther(xmlReqParam);
    }

    @WebMethod(exclude=true)//当前方法不被发布出去
    public Object RequestOther(String object){
//        进行其他服务逻辑处理
//        SayHello sayHello = new SayHello();
//        sayHello.say("服务调用成功");
        return "RequestOther服务响应成功!入参为:"+object;
    }

    public static void main(String[] args) {
        String url = "http://youIP:youPort/ESBWebservice";
        Endpoint publish = Endpoint.publish(url,new EWebService());
        if(publish.isPublished()) {
            System.out.println("=============server is running==============");
        }else {
            System.out.println("=============server is error================");
        }
    }
}

Webservice服务类就已经准备就绪了,直接运行该类中的main方法即可发布Webservice服务。

发布服务

运行该类中的main方法,注意修改自己的ip和端口哈。运行后效果如图:
运行main效果图
在浏览器中访问http://youIP:youPort/ESBWebservice?wsdl进行查看服务是否发布成功!如图:
查看wsdl文件
看到这样的界面就表示服务发布成功了!下面说如何进行服务的调用。

Webservice服务的常规调用

常规调用方式如下:

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;

public static void main(String[] args) {
		try {
			String url ="http://youIP:youPort/ESBWebservice?wsdl";
			//生成客户端实例
			JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
			Client client = dcf.createClient(url);
			//服务参数
			String paramString = "参数内容";
			//进行自动代理发起请求
			Object[] obj = client.invoke("RequestDataByJson",paramString);
			System.out.println("调用返回值为:"+obj[0]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

调用结果如图:客户端响应如图
服务成功响应。但是此类调用方法可能存在部分Webservice服务在SOAPUI上面正常调用,但是使用该方法访问时就出现各类异常,导致服务调用不通的问题。

Webservice服务调用常见问题

1、No operation was found with the name

在这里插入图片描述

2、Unmarshalling Error: 意外的元素 (uri:“urn:hl7-org:v3”, local:“return”)。所需元素为<{urn:hl7-org:v3}HIPMessageServerResult>

在这里插入图片描述

3、返回值是一个对象,须进行解析取值

在这里插入图片描述

推荐的Webservice调用方式

本方式是结合了hutool中的调用方式和jdk自带的wsdl解析进行封装的调用方式。

调用所需依赖

// 自定义调用所需依赖
<dependency>
	<groupId>cn.hutool</groupId>
	<artifactId>hutool-all</artifactId>
	<version>5.1.0</version>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.10</version>
</dependency>

调用工具类

package com.zpg.fun.utils;

import cn.hutool.http.webservice.SoapClient;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.ibm.wsdl.PortImpl;
import com.ibm.wsdl.extensions.soap.SOAPAddressImpl;
import com.ibm.wsdl.extensions.soap12.SOAP12AddressImpl;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import javax.wsdl.Definition;
import javax.wsdl.Service;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPMessage;
import java.io.ByteArrayInputStream;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @Author: zp
 * @Description: webservice服务请求工具
 * @Date: 2021/8/24 10:57
 * @Version: 1.0
 */
public class WebserviceUtils {

	public static void main(String[] args) {
        Map<String,Object> params = new HashMap<>();
        params.put("jsonReqParam","you service params....");
        params.put("param2","you service param2....");
        String url = "http://youIP:youPort/ESBWebservice?wsdl";
        String methodName = "RequestDataByJson";
        System.out.println("服务响应值为:"+requestWsdl(url,methodName,params));
	}

	/**
	 * wsdl解析
	 * @param url           wsdl地址
	 * @param methodName    请求的方法名
	 * @param parameter     参数值
	 * @return
	 */
	public static String requestWsdl(String url, String methodName, Map<String, Object> parameter) {
		try {
			WSDLFactory factory = WSDLFactory.newInstance();
			WSDLReader reader = factory.newWSDLReader();
			reader.setFeature("javax.wsdl.verbose", true);
			reader.setFeature("javax.wsdl.importDocuments", true);
			//解析wsdl地址
			Definition def = reader.readWSDL(url);
			// 元素所属命名空间
			String namespaceURI = def.getTargetNamespace();
			String wsdlService = null;
			String soapVersion = SOAPConstants.SOAP_1_1_PROTOCOL;
			//根据wsdl地址和命名空间获取服务和服务所在的绑定名
			Map<QName, Object> map1 = def.getServices();
			for (Map.Entry<QName, Object> vo : map1.entrySet()) {
				wsdlService = vo.getKey().getLocalPart();
			}
			QName sname = new QName(namespaceURI, wsdlService);
			//获取改指定空间下的服务信息
			Service service = def.getService(sname);
			Map<String, Object> ports = service.getPorts();
			Iterator<?> itor = ports.entrySet().iterator();
			while (itor.hasNext()) {
				Map.Entry<String, Object> map = (Map.Entry<String, Object>) itor.next();
				//如果服务的wsdl地址和服务方法名的绑定地址不统一,那么需要获取服务名所在的地址
				PortImpl valueMap = (PortImpl) map.getValue();
				@SuppressWarnings("rawtypes")
				List extensList = valueMap.getExtensibilityElements();
				if (extensList != null) {
					for (int i = 0; i < extensList.size(); i++) {
						//获取服务的绑定地址
						ExtensibilityElement extElement = (ExtensibilityElement) extensList.get(i);
						//获取locationURI 获取后直接访问改地址进行服务消费  不再使用wsdl的地址
						if (extElement instanceof SOAPAddressImpl) {
							SOAPAddressImpl soapAddress = (SOAPAddressImpl) extElement;
							url = soapAddress.getLocationURI();
							soapVersion = SOAPConstants.SOAP_1_1_PROTOCOL;
						}
						if (extElement instanceof SOAP12AddressImpl) {
							SOAP12AddressImpl soapAddress = (SOAP12AddressImpl) extElement;
							url = soapAddress.getLocationURI();
							soapVersion = SOAPConstants.SOAP_1_2_PROTOCOL;
						}
					}
				}
				//避免有些服务提供商将一个服务以多中方式提供而报错  此处获取到后不再获取【如天气查询 soap1.1 soap1.3 httpPost httpGet均提供】
				break;
			}
			return sendMessage(url, namespaceURI, methodName, parameter, soapVersion).trim();
		} catch (Exception e) {
			return "网络错误,请联系管理员"+e.getMessage();
		}
	}

	/**
	 * <p>Title: sendMessage</p>
	 * <p>Description:发送soap请求获取原服务返回值</p>
	 * @param wsdlUrl 		服务地址或者服务所在的binding地址
	 * @param namespaceURI  命名空间
	 * @param methodName    服务名
	 * @param params  		参数map
	 * @param soapVersion   soap版本
	 * @return
	 * @throws Exception
	 */
	private static String sendMessage(String wsdlUrl, String namespaceURI,String methodName,Map<String, Object> params, String soapVersion) {
		try {
			SoapClient client = SoapClient.create(wsdlUrl)
					// 设置要请求的方法,此接口方法前缀为web,传入对应的命名空间
					.setMethod(methodName,namespaceURI)
					// 设置参数,此处自动添加方法的前缀:
					.setParams(params);
			String returnStr = client.send(true);
//			System.out.println("服务端响应信息为:"+returnStr);
			if(StringUtils.isNotBlank(returnStr)) {
				// 不同的服务定义的返回信息节点不同,且所在命名空间不同,导致无法定位取值地点 --》转换为soap消息体进行取值
				return formatSoapString(returnStr,soapVersion);
			}else {
				return  "取值失败;服务端响应信息为:"+returnStr;
			}
		} catch (Exception e1) {
			e1.printStackTrace();
			return "服务调用失败!"+e1.getMessage();
		}
	}
	/**
	 * <p>Title: formatSoapString</p>
	 * <p>Description: 根据soap返回的消息体字符串和soap版本进行字符串转soapMessage消息体</p>
	 * @param soapString
	 * @param soapVersion
	 * @return
	 */
	public static String formatSoapString(String soapString,String soapVersion){
		try{
			MessageFactory msgFactory = null;
			if("SOAP 1.1 Protocol".equals(soapVersion)) {
				msgFactory = MessageFactory.newInstance();
			}
			if("SOAP 1.2 Protocol".equals(soapVersion)) {
				msgFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
			}
			SOAPMessage reqMsg = msgFactory.createMessage(new MimeHeaders(), new ByteArrayInputStream(soapString.getBytes(Charset.forName("UTF-8"))));
//			reqMsg.saveChanges();保存修改后的soapmessage
			if(null!=reqMsg) {
				Document doc = reqMsg.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
				//soapBody中的返回信息节点
				Node node = doc.getFirstChild();
				if(node != null) {
					return node.getTextContent().trim();
				}else {
					return "返回值取值失败";
				}
			}else{
				return "返回值取值失败";
			}
		}catch (Exception e){
			return null;
		}
	}
}

经验证,用这样的方式调用就可以完美避免上面说遇到的这些问题了!

调用带WSS认证的Webservice服务

在接口对接过程中经常遇到第三方开发的Webservice服务添加了WSS认证,在服务调用的时候需要进行特殊的配置才能访问服务信息。

添加WSS认证所需依赖

// WSS所需依赖
 <!--wss4j begin-->
 <dependency>
     <groupId>org.springframework.ws</groupId>
     <artifactId>spring-ws-security</artifactId>
     <version>3.1.1</version>
 </dependency>
 <dependency>
     <groupId>org.apache.ws.security</groupId>
     <artifactId>wss4j</artifactId>
     <version>1.6.19</version>
 </dependency>
 <dependency>
     <groupId>org.apache.cxf</groupId>
     <artifactId>cxf-rt-ws-security</artifactId>
     <version>3.2.8</version>
     <exclusions>
         <exclusion>
             <artifactId>cxf-rt-bindings-soap</artifactId>
             <groupId>org.apache.cxf</groupId>
         </exclusion>
         <exclusion>
             <artifactId>wss4j-ws-security-dom</artifactId>
             <groupId>org.apache.wss4j</groupId>
         </exclusion>
     </exclusions>
 </dependency>
 <!--wss4j end-->

添加获取认证回调类

主要作用用于获取WSS认证后的回调信息,让client可以有权限进行服务调用。

import org.apache.wss4j.common.ext.WSPasswordCallback;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zp
 * ws CallbackHandler
 */
public class PasswordHandler implements CallbackHandler {
    private Map<String, String> passwords = new HashMap<String, String>();
    public PasswordHandler(String user, String psw) {
        passwords.put(user, psw);
    }
    public void handle(Callback[] callbacks) throws IOException,UnsupportedCallbackException {
        for (int i = 0; i < callbacks.length; i++) {
            WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
            String identifier = pc.getIdentifier();//用户名
            int usage = pc.getUsage();//验证方式
            if (usage == WSPasswordCallback.USERNAME_TOKEN) {
                pc.setPassword(passwords.get(identifier));
            } else if (usage == WSPasswordCallback.SIGNATURE) {
                pc.setPassword(passwords.get(identifier));
            }
        }
    }
}

完善服务调用工具类

将前面的调用工具进行完善,提供了2种服务调用方案,CxfInvoke为较常见的调用方式,在此基础上添加了WSS认证的服务调用功能,requestWsdl调用场景为发布的Webservice服务的wsdl地址和服务所在的SOAPAddress不对应的时候,采用该方法可以成功调用。

import cn.hutool.http.webservice.SoapClient;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.ibm.wsdl.PortImpl;
import com.ibm.wsdl.extensions.soap.SOAPAddressImpl;
import com.ibm.wsdl.extensions.soap12.SOAP12AddressImpl;
import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.wss4j.dom.handler.WSHandlerConstants;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import javax.wsdl.Definition;
import javax.wsdl.Service;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPMessage;
import java.io.ByteArrayInputStream;
import java.nio.charset.Charset;
import java.util.*;

/**
 * @Author: zp
 * @Description: webservice服务请求工具
 * @Date: 2021/8/24 10:57
 * @Version: 1.0
 */
public class WebserviceUtils {

    public static void main(String[] args) {
        WebserviceUtils webserviceUtils = new WebserviceUtils();
        Map<String,Object> params = new HashMap<>();
        params.put("jsonReqParam","参数1");
        params.put("param2","参数2");
        String url = "http://192.168.4.16:8081/ESBWebservice?wsdl";
        String methodName = "RequestDataByJson";
        System.out.println("服务响应值1为:"+webserviceUtils.requestWsdl(url,methodName,params));
        
        List<Object> paramList = new ArrayList<>();
        paramList.add("jsonReqParam参数1");
        paramList.add("参数2");
        System.out.println("服务响应值2为:"+webserviceUtils.CxfInvoke(url,methodName,paramList,false,"","","",""));
    }

    /**
     * webservice服务调用方法1 wsdl解析+SoapClient
     * @param url           wsdl地址
     * @param methodName    请求的方法名
     * @param parameter     参数值
     * @return
     */
    public String requestWsdl(String url, String methodName, Map<String, Object> parameter) {
        try {
            WSDLFactory factory = WSDLFactory.newInstance();
            WSDLReader reader = factory.newWSDLReader();
            reader.setFeature("javax.wsdl.verbose", true);
            reader.setFeature("javax.wsdl.importDocuments", true);
            //解析wsdl地址
            Definition def = reader.readWSDL(url);
            // 元素所属命名空间
            String namespaceURI = def.getTargetNamespace();
            String wsdlService = null;
            String soapVersion = SOAPConstants.SOAP_1_1_PROTOCOL;
            //根据wsdl地址和命名空间获取服务和服务所在的绑定名
            Map<QName, Object> map1 = def.getServices();
            for (Map.Entry<QName, Object> vo : map1.entrySet()) {
                wsdlService = vo.getKey().getLocalPart();
            }
            QName sname = new QName(namespaceURI, wsdlService);
            //获取改指定空间下的服务信息
            Service service = def.getService(sname);
            Map<String, Object> ports = service.getPorts();
            Iterator<?> itor = ports.entrySet().iterator();
            while (itor.hasNext()) {
                Map.Entry<String, Object> map = (Map.Entry<String, Object>) itor.next();
                //如果服务的wsdl地址和服务方法名的绑定地址不统一,那么需要获取服务名所在的地址
                PortImpl valueMap = (PortImpl) map.getValue();
                @SuppressWarnings("rawtypes")
                List extensList = valueMap.getExtensibilityElements();
                if (extensList != null) {
                    for (int i = 0; i < extensList.size(); i++) {
                        //获取服务的绑定地址
                        ExtensibilityElement extElement = (ExtensibilityElement) extensList.get(i);
                        //获取locationURI 获取后直接访问改地址进行服务消费  不再使用wsdl的地址
                        if (extElement instanceof SOAPAddressImpl) {
                            SOAPAddressImpl soapAddress = (SOAPAddressImpl) extElement;
                            url = soapAddress.getLocationURI();
                            soapVersion = SOAPConstants.SOAP_1_1_PROTOCOL;
                        }
                        if (extElement instanceof SOAP12AddressImpl) {
                            SOAP12AddressImpl soapAddress = (SOAP12AddressImpl) extElement;
                            url = soapAddress.getLocationURI();
                            soapVersion = SOAPConstants.SOAP_1_2_PROTOCOL;
                        }
                    }
                }
                //避免有些服务提供商将一个服务以多中方式提供而报错  此处获取到后不再获取【如天气查询 soap1.1 soap1.3 httpPost httpGet均提供】
                break;
            }
            return sendMessage(url, namespaceURI, methodName, parameter, soapVersion).trim();
        } catch (Exception e) {
            return "网络错误,请联系管理员"+e.getMessage();
        }
    }
    /**
     * <p>Title: sendMessage</p>
     * <p>Description:发送soap请求获取原服务返回值</p>
     * @param wsdlUrl 		服务地址或者服务所在的binding地址
     * @param namespaceURI  命名空间
     * @param methodName    服务名
     * @param params  		参数map
     * @param soapVersion   soap版本
     * @return
     * @throws Exception
     */
    private String sendMessage(String wsdlUrl, String namespaceURI,String methodName,Map<String, Object> params, String soapVersion) {
        try {
            SoapClient client = SoapClient.create(wsdlUrl)
                    // 设置要请求的方法,此接口方法前缀为web,传入对应的命名空间
                    .setMethod(methodName,namespaceURI)
                    // 设置参数,此处自动添加方法的前缀:
                    .setParams(params);
            String returnStr = client.send(true);
            if(StringUtils.isNotBlank(returnStr)) {
                // 不同的服务定义的返回信息节点不同,且所在命名空间不同,导致无法定位取值地点 --》转换为soap消息体进行取值
                return formatSoapString(returnStr,soapVersion);
            }else {
                return  "取值失败;服务端响应信息为:"+returnStr;
            }
        } catch (Exception e1) {
            e1.printStackTrace();
            return "服务调用失败!"+e1.getMessage();
        }
    }
    /**
     * <p>Title: formatSoapString</p>
     * <p>Description: 根据soap返回的消息体字符串和soap版本进行字符串转soapMessage消息体</p>
     * @param soapString
     * @param soapVersion
     * @return
     */
    public String formatSoapString(String soapString,String soapVersion){
        try{
            MessageFactory msgFactory = null;
            if("SOAP 1.1 Protocol".equals(soapVersion)) {
                msgFactory = MessageFactory.newInstance();
            }
            if("SOAP 1.2 Protocol".equals(soapVersion)) {
                msgFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
            }
            SOAPMessage reqMsg = msgFactory.createMessage(new MimeHeaders(), new ByteArrayInputStream(soapString.getBytes(Charset.forName("UTF-8"))));
//			reqMsg.saveChanges();保存修改后的soapmessage
            if(null!=reqMsg) {
                Document doc = reqMsg.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
                //soapBody中的返回信息节点
                Node node = doc.getFirstChild();
                if(node != null) {
                    return node.getTextContent().trim();
                }else {
                    return "返回值取值失败";
                }
            }else{
                return "返回值取值失败";
            }
        }catch (Exception e){
            return null;
        }
    }
    /**
     * webservice服务调用方法2
     * @param wsUrl wsdl地址
     * @param methodName 方法名
     * @param params 参数
     * @param wssAuEnable 是否有WSS认证
     * @param action 认证服务名
     * @param pwType 密码传输类型
     * @param userName 认证用户名
     * @param pwd 认证密码
     * @return
     */
    public String CxfInvoke(String wsUrl,String methodName,List<Object> params,Boolean wssAuEnable,String action,String pwType,String userName,String pwd) {
        try {
            //生成客户端实例
            JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
            Client client = dcf.createClient(wsUrl);
            if(wssAuEnable){
                setWssAuth(client, action, pwType, userName, pwd);
            }
            Object[] obj = client.invoke(methodName,params.toArray());
            return obj[0].toString();
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }

    /**
     * 设置wssAuth权限认证
     * @param client webservice 客户端
     * @param action 服务名  取值见WSHandlerConstants.ACTION
     * @param pswType 密码传输类型 取值见WSHandlerConstants.PASSWORD_TYPE
     * @param user 用户名
     * @param psw 密码
     */
    private void setWssAuth(Client client, String action, String pswType, String user, String psw) {
        Map<String, Object> outProps = new HashMap<>();
        outProps.put(WSHandlerConstants.ACTION, action);
        outProps.put(WSHandlerConstants.USER, user);
        outProps.put(WSHandlerConstants.PASSWORD_TYPE, pswType);
        // 指定在调用远程ws之前触发的回调函数WsClinetAuthHandler,其实类似于一个拦截器
//        outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,
//                PasswordHandler.class.getName());
        PasswordHandler ph = new PasswordHandler(user, psw);
        outProps.put(WSHandlerConstants.PW_CALLBACK_REF, ph);
        ArrayList list = new ArrayList();
        // 添加cxf安全验证拦截器,必须
        list.add(new SAAJOutInterceptor());
        list.add(new WSS4JOutInterceptor(outProps));
        client.getOutInterceptors().addAll(list);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值