`

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

头部信息不能为空!

 

  • 大小: 13.5 KB
  • 大小: 27 KB
  • 大小: 31.8 KB
  • 大小: 13.2 KB
分享到:
评论

相关推荐

    Web Service SOAP Client set SOAP Header

    要设置SOAP Header以便在Web Service调用中添加这些验证信息,我们可以创建一个自定义的SOAP Handler。以下是一个Java实现的例子,展示了如何在SOAP Message中插入这样的SOAP Header: ```java import javax.xml....

    使用jaxws建立webservice客户端并实现soap消息的handler验证示例

    在本文中,我们将深入探讨如何使用Java API for XML Web Services (JAX-WS) 创建一个Web服务客户端,并实现SOAP消息的Handler验证。JAX-WS是Java平台标准的一部分,用于处理基于SOAP的消息交换,它提供了方便的方式...

    实现隐式和显式 SOAP 消息头

    SOAP(Simple Object Access ...通过源码解析和利用相关工具,我们可以更好地控制和处理SOAP通信过程中的各种信息。在实际开发中,确保消息头正确无误地传递和处理,对于保证服务的稳定性和安全性具有重要意义。

    PHP webservice教程,soap wsdl密码验证,webservice高级应用

    在PHP中,我们可以使用SoapClient和SoapServer类来处理SOAP请求和响应。例如,使用SoapClient与远程Web服务进行交互,而SoapServer则用于创建和运行本地的SOAP服务。 WSDL则是用来描述Web服务的接口,它定义了服务...

    Android使用ksoap2+协程+handler实现WebService

    本示例主要探讨如何在Android应用中利用kotlin的协程(Coroutines)和ksoap2库来实现对WebService的调用,并解决在API 30及以上版本中Handler过时的问题。 一、ksoap2库介绍 ksoap2是一个轻量级的开源库,专为...

    使用 .NET 调用有自定义 Handler 验证的 XFire Web 服务

    在 .NET 中,Web 服务通常通过 SOAP(Simple Object Access Protocol)协议进行通信,这允许不同平台的应用程序之间交换结构化数据。为了调用 Web 服务,开发者可以使用 .NET 的 `System.Web.Services` 命名空间中的...

    soap(java).rar_DEMO_soap java

    在Java中,我们通常使用JAX-WS(Java API for XML Web Services)来处理SOAP请求和响应。JAX-WS提供了一种方便的方式来创建和消费SOAP服务。下面将详细介绍如何使用Java和JAX-WS实现SOAP通信: 1. **创建SOAP服务**...

    JAX-WS SOAP header设值

    4. **MessageHandler**:实现`javax.xml.ws.handler.MessageContext`和`javax.xml.ws.handler.soap.SOAPHandler`接口,创建自定义的消息处理器来设置或处理SOAP头。 5. **JAXB**:利用JAXB将Java对象转换为XML,反之...

    soapheader的创建和解析

    服务端解析SOAP Header的关键在于创建一个`MessageHandler`实现,该实现将检查并处理传入的SOAP消息中的Header部分。以下是一个简单的例子: ```java import javax.xml.ws.handler.soap.SOAPMessageContext; import...

    CXF客户端添加soapHeader代码 + jar包 + apache-cxf-3.1.15

    3. 编写SOAP Header处理逻辑:接下来,我们需要创建一个类来表示Header并实现`javax.xml.ws.handler.soap.SOAPHandler&lt;SOAPMessageContext&gt;`接口。 ```java import javax.xml.soap.SOAPHeader; import javax.xml....

    SOAP与Java编程指南

    4. **SOAP消息处理**:在Java中,可以通过实现`MessageHandler`接口来添加自定义的SOAP消息处理逻辑。这使得开发者能够在消息发送前或接收后对其进行处理。 5. **SOAP服务的部署与测试**:Java开发者可以将SOAP服务...

    ios-TSoapRequest iOS下的soap请求的封装.zip

    在iOS开发中,进行Web服务交互时,常常会遇到SOAP(Simple Object Access Protocol)协议的使用,这是一种基于XML的协议,用于交换...在实际项目中,结合“ios-TSoapRequest”,可以更高效地处理SOAP相关的网络请求。

    soap资料及面试资料,机struts资料,级soapheader资料.zip

    5. 每个Header元素可以有一个或多个处理者(Handler),负责解释和处理Header中的信息。 【其他文件关联知识点】 1. "NTT面试.doc"可能包含NTT公司关于SOAP、Axis2或Struts的面试问题和解答,可以帮助求职者准备...

    使用wsdl2objc实现Soap

    在iOS开发中,有时我们需要与使用SOAP协议的Web服务进行交互。SOAP(Simple Object Access Protocol)是一种基于XML的网络通信协议,用于交换结构化的信息。本文将深入探讨如何使用`wsdl2objc`工具来实现SOAP请求,...

    jax-rpc soap头扩展 客户端,服务端例子

    SOAP头扩展则是SOAP消息中用于传递附加信息的重要组成部分,如认证、事务控制等。本文将深入探讨如何在JAX-RPC中使用SOAP头扩展,同时提供客户端和服务端的实例。 ### 一、SOAP头扩展基础 SOAP头是SOAP消息的一个...

    SOAPHEADER方法增强WebService安全性代码

    首先,我们需要了解为什么要在SOAP Header中处理安全性。传统的HTTP基础认证或Cookie认证方式可能存在安全隐患,如中间人攻击、数据泄露等。SOAP Header提供了更灵活和强大的安全控制机制,可以实现如用户名/密码...

    在基于WCF的应用程序中处理SOAP异常

    在基于Windows Communication Foundation (WCF) 的应用程序中,处理SOAP异常是确保服务稳定性和健壮性的重要环节。SOAP异常是WCF服务在遇到错误时抛出的,它们以SOAP消息的形式封装了错误信息,以便跨网络传递。本篇...

    soapHeader验证例子

    为了处理SOAP头,可以创建一个实现了`Handler&lt;SOAPMessageContext&gt;`接口的类,重写其`handleMessage`方法来检查或修改SOAP头。 4. **客户端实现**: ClientDemo_WebServiceSoapHeader包含了一个客户端示例,用于...

Global site tag (gtag.js) - Google Analytics