webservice之自定义请求头实现

本文介绍通过两种方法为Webservice客户端添加自定义请求头:一是利用Cxf框架的拦截器,二是通过JDK自带的HandlerResolver接口。两种方法均实现了在发送请求前加入包含token、用户名和密码等信息的自定义头部。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:目前遇到一个调用webservice服务端的程序,需要开发客户端调用程序,但是涉及到自定义请求头,这个有一点麻烦

目前基于http+json的restful大行其道,所以本篇不介绍webservice服务开发过程,详情可自行百度,基于cxf 可开发webservice和restful服务
好的,言归正传,本篇文章将会介绍webservice客户端调用添加自定义请求头的两种方式,一种是jdk,一种借助于cxf框架

自定义请求头格式:

<auth>
<token></token>
<user></user>
<password></password>
</auth>

服务端实现:
自定义头部,需要自定义解析,本例服务端采用的是cxf,所以采用的是
拦截器AbstractPhaseInterceptor,拦截请求,解析头部

public class AuthHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
	private Logger log = Logger.getLogger(AuthHeaderInterceptor.class);
	public AuthHeaderInterceptor() {
		super(Phase.PRE_INVOKE);
	}

	@Override
	public void handleMessage(SoapMessage msg) throws Fault {
		try {
			Header authHeader =null;
		//获取验证头
			List<Header> headers = msg.getHeaders();
			for(Header h:headers){
				if(h.getName().toString().contains("auth")){
					authHeader=h;
					break;
				}
			}
		Element auth = (Element) authHeader.getObject();
		NodeList childNodes = auth.getChildNodes();
		String token,user,password;
		for(int i=0,len=childNodes.getLength();i<len;i++){
				Node item = childNodes.item(i);
				if(item.getNodeName().contains("token")){
					 token=item.getTextContent();
					// do check token
				}
				if(item.getNodeName().contains("user")){
					 user=item.getTextContent();
					// do check user
				}
				if(item.getNodeName().contains("password")){
					password=item.getTextContent();
					 // do check password
				}
		}
		
		} catch (Exception e) {
			e.printStackTrace();
			log.error("权限验证异常");
			throw new Fault(new Exception("请求头auth不合法"));
		}
	}

}

客户端实现
cxf 框架实现:
实现手段,拦截每次请求,添加自定义认证头部;
继承 AbstractSoapInterceptor

import java.util.List;

import javax.xml.namespace.QName;

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

public class AuthHeaderInterceptor extends AbstractSoapInterceptor {
	private String token;
	private String user;
	private String password;

	public AuthHeaderInterceptor(String p, String token, String user, String password) {
		super(p);
		this.token = token;
		this.user = user;
		this.password = password;
	}

	public AuthHeaderInterceptor() {
		super(Phase.WRITE);
	}

	public void handleMessage(SoapMessage message) throws Fault {
		// SoapHeader部分待添加的节点
		QName qName = new QName("auth");
		Document doc = DOMUtils.createDocument();
		// 验证token
		Element tokenEl = doc.createElement("token");
		tokenEl.setTextContent(token);

		Element pwdEl = doc.createElement("password");
		pwdEl.setTextContent(password);
		Element userEl = doc.createElement("user");
		userEl.setTextContent(user);
		Element root = doc.createElement("auth");
		
		
		root.appendChild(tokenEl);
		root.appendChild(userEl);
		root.appendChild(pwdEl);
		// 创建SoapHeader内容
		SoapHeader header = new SoapHeader(qName, root);
		// 添加SoapHeader内容
		List<Header> headers = message.getHeaders();
		headers.add(header);
	}

}


客户端调用,添加到outInterceptors
	Client client= ClientProxy.getClient(service);
	AuthHeaderInterceptor authHeaderInterceptor = new AuthHeaderInterceptor("token","user","password");
	client.getOutInterceptors().add(authHeaderInterceptor)
services.xxx(调用)

jdk 实现:
和cxf 原理差不多,都是在请求之前添加头部,不过实现的是HandlerResolver 接口

//首先实现:添加头部逻辑
public class RequesterCredentials implements SOAPHandler<SOAPMessageContext> {
	private String token;
	private String user;
	private String password;

	public RequesterCredentials(String token, String user, String password) {
		super();
		this.token = token;
		this.user = user;
		this.password = password;
	}

	public String getToken() {
		return token;
	}

	public void setToken(String token) {
		this.token = token;
	}

	public String getUser() {
		return user;
	}

	public void setUser(String user) {
		this.user = user;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public Set<QName> getHeaders() {
		return null;
	}

	@Override
	public void close(MessageContext context) {
	}

	@Override
	public boolean handleFault(SOAPMessageContext context) {
		// TODO return true
		return true;
	}

	@Override
	public boolean handleMessage(SOAPMessageContext context) {
		addRequesterCredentials(context);
		return true;
	}

	private void addRequesterCredentials(SOAPMessageContext context) {
		try {
			Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
			
			if (outboundProperty.booleanValue()) {
				SOAPMessage message = context.getMessage();

				SOAPHeader header = message.getSOAPHeader();
				if (header == null) {
					message.getSOAPPart().getEnvelope().addHeader();
					header = message.getSOAPHeader();
				}
				SOAPElement authenticationToken = header.addChildElement("auth", "", "");
				authenticationToken.addChildElement("user").addTextNode(user);
				authenticationToken.addChildElement("password").addTextNode(password);
				authenticationToken.addChildElement("token").addTextNode(token);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public RequesterCredentials() {

	}

}
//实现 HandlerResolver 接口

public class HeaderHandlerResolver implements HandlerResolver {
	private RequesterCredentials requesterCredentials;

	public HeaderHandlerResolver(RequesterCredentials requesterCredentials){
		this.requesterCredentials=requesterCredentials;
	}
	@Override
	public List getHandlerChain(PortInfo portInfo) {
		return Arrays.asList(requesterCredentials);
	}


	
	
}


使用:
1.首先使用wsdl工具生成java 客户端代码
2.实例化service
如:	MathService mathService = new MathService("wsdl address");
3. 为service 添加 HeaderHandlerResolver
RequesterCredentials  r=new RequesterCredentials ("token","user","password");
HeaderHandlerResolver  headerHandlerResolver=new HeaderHandlerResolver (r);
mathService .setHandlerResolver(headerHandlerResolver);
调用
mathService .xxx

最终效果:
这里写图片描述

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值