soap中Handler的处理

通过java提供的wsimport命令把wsdl导成.java.class,如下图:

 

生成文件如下图:

 

接着创建独立的java项目,把这些java文件拷贝到src下面,再次创建客户MyClient.java

package com.webservice;

public class MyClient {
	public static void main(String[] args) {
		MyServiceImplService msis = new MyServiceImplService();
		IMyService ms = msis.getMyServiceImplPort();
		
		try {
			ms.login("admin", "11111");
		} catch (UserException_Exception e) {
			System.out.println(e.getMessage());
		}
	}
}

 

运行结果:

用户名或密码不正确!

 

现在想这样一个问题:服务器已经把某个方法发布了(不能再更改了),这个时候,有这样一个需求,在客户端调用服务端方法传递数据信息的时候,需要传递一些其他的信息(比如:头信息),这时在客户端貌似没法处理这样的需求了,那么,针对于这样的需求,引出一个新的知识点:handler,它有两种类型:LogicHandlerSOAPHandler,前者只能获取SOAPBody的信息,后者可以获取SOAPMessage的信息。用的比较多的是SOAPHandler

创建一个handler(实现SOAPHandler接口)

HeaderHandler.java

package com.webservice.handler;

import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

public class HeaderHandler implements SOAPHandler<SOAPMessageContext> {

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

	@Override
	public void close(MessageContext context) {

	}

	@Override
	public boolean handleFault(SOAPMessageContext context) {
		System.out.println("error");
		return false;
	}

	@Override
	public boolean handleMessage(SOAPMessageContext context) {
		try {
			boolean out = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
			if (out) {// 客户端这里是发送消息,因此在out的时候发送
				SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
				SOAPHeader header = envelope.getHeader();
				if (header == null) {
					header = envelope.addHeader();
				}
				QName qname = new QName("http://www.webservice.com", "licenseInfo", "ns");
				header.addHeaderElement(qname).setValue("12345");
			}
		} catch (SOAPException e) {
			e.printStackTrace();
		}
		return true;
	}

}

 

handleFault方法是处理异常错误的。

classpath目录下,创建handler的配置文件

handler-chain.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<javaee:handler-chains xmlns:javaee="http://java.sun.com/xml/ns/javaee"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<javaee:handler-chain>
		<javaee:handler>
			<javaee:handler-class>com.webservice.handler.HeaderHandler
			</javaee:handler-class>
		</javaee:handler>
	</javaee:handler-chain>
</javaee:handler-chains>

 

修改生成的MyServiceImplService.java文件,在此类类名上添加注解:@HandlerChain(file = "handler-chain.xml")

 

(1)为了清楚地查看客户端的信息发送服务端的时候信息中包含头信息,修改MyClient.java

package com.webservice;

import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.ws.soap.SOAPFaultException;

public class MyClient {
	public static void main(String[] args) throws MalformedURLException {
		// MyServiceImplService msis = new MyServiceImplService();
		
		URL url = new URL("http://localhost:6666/server?wsdl");
		QName qName = new QName("http://www.webservice.com", "MyServiceImplService");
		MyServiceImplService msis = new MyServiceImplService(url, qName);
		IMyService ms = msis.getMyServiceImplPort();

		try {
			ms.login("admin", "11111");
		} catch (UserException_Exception e) {
			System.out.println(e.getMessage());
		} catch (SOAPFaultException e) {
			System.out.println(e.getMessage());
		}
	}
}

 

然后,使用eclipseTCP/IP Monitor工具进行捕获,如下图:

 

其中,6666端口为监听端口(和客户端代码设置的端口一致)9999端口为发布的服务端端口,类型选择TCP/IP,点击ok后,点击start启动6666监听端口,再次运行MyClient.java,运行结果:

error

用户名或密码不正确!

 

而在TCP/IP Monitor工具窗口中,很清楚地捕获到了发往服务端的信息中,包含头信息,如下图:

 

(2)为了清楚地查看服务端接收的信息中包含客户端发过来的头信息,在服务端创建一个handler(实现SOAPHandler接口)

LicenseHandler.java(这里只针对loginaddUser方法做头信息的处理,传递过来的信息可能有头信息,也可能没有头信息,如果没有,做相应的异常处理)

 

package com.test.handler;

import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPHeader;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import javax.xml.ws.soap.SOAPFaultException;

import org.w3c.dom.NodeList;

public class LicenseHandler implements SOAPHandler<SOAPMessageContext> {

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

	@Override
	public void close(MessageContext context) {

	}

	@Override
	public boolean handleFault(SOAPMessageContext context) {
		return false;
	}

	@Override
	public boolean handleMessage(SOAPMessageContext context) {
		try {
			boolean out = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
			if (!out) {// 服务端这里是获取消息,因此在in的时候获取
				SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
				SOAPHeader header = envelope.getHeader();
				SOAPBody body = envelope.getBody();
				String localName = body.getChildNodes().item(0).getLocalName();
				if ("login".equals(localName) || "addUser".equals(localName)) {
					if (header.hasChildNodes()) {
						NodeList nl = (NodeList) header.getElementsByTagName("ns:licenseInfo");
						System.out.println(nl.item(0).getTextContent());
					} else {
						SOAPFault fault = body.addFault();
						fault.setFaultString("头部信息不能为空!");
						throw new SOAPFaultException(fault);
					}
				}
			}
		} catch (SOAPException e) {
			e.printStackTrace();
		}
		return true;
	}

}

 

classpath目录下,创建handler的配置文件

handler-chain.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<javaee:handler-chains xmlns:javaee="http://java.sun.com/xml/ns/javaee"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<javaee:handler-chain>
		<javaee:handler>
			<javaee:handler-class>com.test.handler.LicenseHandler</javaee:handler-class>
		</javaee:handler>
	</javaee:handler-chain>
</javaee:handler-chains>

 

修改服务端MyServiceImpl.java文件,在此类类名上添加注解:@HandlerChain(file = "handler-chain.xml")

 

再次运行客户端MyClient.java

客户端运行结果:

error

用户名或密码不正确!

服务端运行结果:

12345

【运行结果说明服务端成功获取到了客户端发来的头信息。】

 

如果客户端发信息的时候不携带头信息,也就是说清空HeaderHandler.java中的handleMessage方法

再次运行客户端MyClient.java

客户端运行结果:

error

头部信息不能为空!

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值