`
schy_hqh
  • 浏览: 558089 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

通过Handler添加HEADER

 
阅读更多

LogicHandler   只能获取SOAPBody的信息

SOAPHandler    可以获取SOAPMessage的信息

可以使用多个Handler,但是最终执行顺序:
客户端:LogicHandler   ---> SOAPHandler   
服务端:SOAPHandler    ---> LogicHandler  


Handler的使用步骤

1.定义一个类实现SOAPHandler并指定泛型:SOAPMessageContext
2.实现接口中的方法,在handleMessage(SOAPMessageContext context)中编写代码
3.配置handler-chain.xml
4.在客户端的服务实现类上使用@HandlerChain(file="handler-chain.xml")声明配置

package com.hqh.soap.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.soap.SOAPMessage;
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 boolean handleMessage(SOAPMessageContext context) {
		//在发送soap消息的时候,加入头信息
		try {
			//判断消息是发送还是接收:true 往外推送  false 接收数据
			Boolean outbound = (Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
			if(outbound) {
				SOAPMessage message = context.getMessage();
				//判断message中是否存在header
				SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
				SOAPHeader header = envelope.getHeader();
				if(header==null) {
					header = envelope.addHeader();
				}
				String ns = "http://soap.hqh.com/";
				QName qName = new QName(ns, "license", "nn");
				header.addHeaderElement(qName).setValue("abc123");
			}
		} catch (SOAPException e) {
			e.printStackTrace();
		} finally {
			
		}
		return true;
	}
	/**
	 * 出现异常本方法执行
	 */
	@Override
	public boolean handleFault(SOAPMessageContext context) {
		System.out.println("error!");
		return false;
	}

	@Override
	public void close(MessageContext context) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public Set<QName> getHeaders() {
		// TODO Auto-generated method stub
		return null;
	}

}




handler-chain.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.hqh.soap.handler.HeaderHandler</javaee:handler-class>
		</javaee:handler>
	</javaee:handler-chain>
</javaee:handler-chains>


/**
 * This class was generated by the JAX-WS RI.
 * JAX-WS RI 2.1.6 in JDK 6
 * Generated source version: 2.1
 * 
 */
@WebServiceClient(name = "MyServiceImplService", targetNamespace = "http://soap.hqh.com/", wsdlLocation = "http://localhost:8888/ms?wsdl")
@HandlerChain(file="handler-chain.xml")
public class MyServiceImplService
    extends Service
{
 ...
}


通过TCP/IP Monitor查看交互的信息

window-preference-Run/Debug-TCP/IP Monitor-add
local monitor port:8889 发送方端口
host name:localhost
port:8888 服务端的端口
type:tcp/ip
start monitor!


package com.hqh.soap.test;

import static org.junit.Assert.*;

import java.net.URL;

import javax.xml.namespace.QName;

import org.junit.Test;

import com.hqh.soap.IMyService;
import com.hqh.soap.MyServiceImplService;
import com.hqh.soap.UserException_Exception;

public class TestHandlerChain {

	@Test
	public void test() throws Exception {
		URL url = new URL("http://localhost:8889/ms?wsdl");
		QName qname = new QName("http://soap.hqh.com/", "MyServiceImplService");
		MyServiceImplService serviceImpl = new MyServiceImplService(url,qname);
		IMyService service = serviceImpl.getMyServiceImplPort();
		try {
			service.login("admin", "admin");
		} catch (UserException_Exception e) {
			System.out.println("出错了:"+e.getMessage());
		}
	}

}



通过tcpM可以看到发送的消息已经添加了header头信息:
<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
	<S:Header>
		<nn:license xmlns:nn="http://soap.hqh.com/">abc123</nn:license>
	</S:Header>
	<S:Body>
		<ns2:login xmlns:ns2="http://soap.hqh.com/">
			<username xmlns="">admin</username>
			<pwd xmlns="">admin</pwd>
		</ns2:login>
	</S:Body>
</S:Envelope>



服务端获取头消息中的内容
1.在服务端编写Handler,通过Handler截取消息
2.在服务端显示定义一个参数来获取信息(基于契约优先的方法使用webservice)


客户端和服务端都使用Handler对消息进行加工和处理
package com.hqh.soap.handler;

import java.io.IOException;
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.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

/**
 * 客户端
 * 通过调用的方法名决定是否加入license信息
 */
public class HeaderHandler implements SOAPHandler<SOAPMessageContext> {
	
	/**
	 * 客户端与服务端都会先执行本方法处理消息,再发送消息
	 */
	@Override
	public boolean handleMessage(SOAPMessageContext context) {
		//在发送soap消息的时候,加入头信息
		try {
			//判断消息是发送还是接收:true 往外推送  false 接收数据
			Boolean outbound = (Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
			//出
			if(outbound) {
				SOAPMessage message = context.getMessage();
				//判断message中是否存在header
				SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
				SOAPHeader header = envelope.getHeader();
				SOAPBody body = envelope.getBody();
				//如果调用服务端的login方法,则在header中加入license信息
				if("login".equals(body.getChildNodes().item(0).getLocalName())) {
					if(header==null) {
						header = envelope.addHeader();
					}
					String ns = "http://soap.hqh.com/";
					QName qName = new QName(ns, "license", "nn");
					header.addHeaderElement(qName).setValue("FGEWRWE34654GFG");
				}
				//将消息打印到控制台
				message.writeTo(System.out);
			}
			
		} catch (SOAPException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			
		}
		return true;
	}
	/**
	 * 出现异常本方法执行
	 */
	@Override
	public boolean handleFault(SOAPMessageContext context) {
		System.out.println("error!");
		return false;
	}

	@Override
	public void close(MessageContext context) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public Set<QName> getHeaders() {
		// TODO Auto-generated method stub
		return null;
	}

}



服务端添加配置文件
<?xml version="1.0" encoding="UTF-8"?>
<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.hqh.soap.handler.LicenseHandler</javaee:handler-class>
		</javaee:handler>
	</javaee:handler-chain>
</javaee:handler-chains>


服务端的实现类上声明handler
package com.hqh.soap;

import java.util.ArrayList;
import java.util.List;

import javax.jws.HandlerChain;
import javax.jws.WebService;

@WebService(endpointInterface="com.hqh.soap.IMyService")
@HandlerChain(file="handler-chain.xml")//声明handler配置文件
public class MyServiceImpl implements IMyService {

	private static List<User> users = new ArrayList<User>();
	
	public MyServiceImpl() {
		users.add(new User(1,"admin","admin"));
	}
	
	@Override
	public int add(int a, int b) {
		System.out.println("MyServiceImpl.add()");
		return a+b;
	}

	@Override
	public User addUser(User user) {
		users.add(user);
		return user;
	}

	@Override
	public User login(String username, String pwd) throws UserException {
		System.out.println("MyServiceImpl.login()");
		for(User user:users) {
			if(username.equals(user.getName()) && pwd.equals(user.getPwd()))
				return user;
		}
		//这里抛出的异常类型如果与接口中声明的异常类型一致,那么服务端将不抛出此异常,而是直接通过soap message将异常传递到客户端
		throw new UserException("用户不存在");
		//抛出运行时异常与接口声明的异常不同,服务端会自己抛出异常,客户端也能接收到异常信息
//		throw new RuntimeException("用户不存在");
	}

	@Override
	public List<User> list(String authInfo) {
		System.out.println(authInfo);
		return users;
	}

}




package com.hqh.soap.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.soap.SOAPMessage;
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.Node;
import org.w3c.dom.NodeList;
/**
 * 服务器端
 * 根据当前调用服务的方法名确定是否需要对license进行验证
 */
public class LicenseHandler implements SOAPHandler<SOAPMessageContext> {

	@Override
	public boolean handleMessage(SOAPMessageContext context) {
		try {
			Boolean outbound = (Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
			//入
			if(!outbound) {
				SOAPMessage message = context.getMessage();
				SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
				SOAPHeader header = envelope.getHeader();
				SOAPBody body = envelope.getBody();
				Node methodNode = body.getChildNodes().item(0);
				//获取访问服务的方法名
				String method = methodNode.getLocalName();
				//不是login方法就不进行license的验证
				if(!"login".equals(method)) {
					return true;
				}
				if(header==null || header.getFirstChild()==null) {
					SOAPFault fault = body.addFault();
					fault.setFaultString("license为空,验证不通过!");
					throw new SOAPFaultException(fault);
				} 
				NodeList nodeList = header.getElementsByTagName("nn:license");
				Node node = nodeList.item(0);
				//node =header.getChildNodes().item(0);
				System.out.println("客户端带过来的license:"+node.getTextContent());
			}
		} catch (SOAPException e) {
			e.printStackTrace();
		}
		return true;
	}

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

	@Override
	public void close(MessageContext context) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public Set<QName> getHeaders() {
		// TODO Auto-generated method stub
		return null;
	}

}



package com.hqh.soap.test;

import static org.junit.Assert.*;

import java.net.URL;

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

import org.junit.Test;

import com.hqh.soap.IMyService;
import com.hqh.soap.MyServiceImplService;
import com.hqh.soap.User;
import com.hqh.soap.UserException_Exception;

public class TestHandlerChain {

	@Test
	public void test() throws Exception {
		URL url = new URL("http://localhost:8889/ms?wsdl");
		QName qname = new QName("http://soap.hqh.com/", "MyServiceImplService");
		MyServiceImplService serviceImpl = new MyServiceImplService(url,qname);
		IMyService service = serviceImpl.getMyServiceImplPort();
		try {
			//调用服务端的login()需要在header中加入license
			User user = service.login("admin", "admin");
			System.out.println();
			System.out.println("user id:"+user.getId());
			
			//调用服务端的其它方法不需要加license到header中
			long result = service.add(1, 1);
			System.out.println();
			System.out.println(result);
			
		} catch (UserException_Exception e) {
			System.out.println("出错了:"+e.getMessage());
		} catch (SOAPFaultException e) {
			System.out.println(e.getMessage());
		}
	}

}

分享到:
评论

相关推荐

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

    // 添加Header // ... return true; } catch (Exception e) { throw new RuntimeException("Failed to set SOAP Header", e); } } } ``` 4. 注册和使用Handler:在客户端调用服务之前,我们需要将自定义的...

    Banner实现轮播图(RecyclerView添加Header)实例 下载

    本文将深入探讨如何使用RecyclerView结合Banner库来实现一个高效的轮播图功能,同时添加Header以增强用户体验。 首先,RecyclerView是Android提供的一种高效、可滚动的视图容器,用于显示大量数据集合。它通过...

    PullHeadGridView添加header

    本篇将详细讲解如何在PullToRefreshGridView中添加Header视图,即"PullHeadGridView"的实现方法。 首先,我们需要了解PullToRefreshGridView的基本原理。它是基于开源库`android-pulltorefresh`的一个扩展,该库由...

    Web Service SOAP Client set SOAP Header

    这样,每次通过客户端代理调用Web Service时,都会自动添加预设的SOAP Header,从而实现身份验证和其他自定义功能。请注意,实际项目中需要替换`your_username`和`your_password`为真实的用户名和密码。同时,为了...

    soap中Handler的处理

    例如,我们可以创建一个处理Header信息的Handler,检查请求的认证信息,或者在响应中添加额外的日志信息。 在实际应用中,Handler的使用场景多种多样。例如,对于安全性需求,我们可以创建一个Handler来实现WS-...

    WebService 添加头部验证信息

    当我们谈论"WebService添加头部验证信息"时,通常是指在发送SOAP(Simple Object Access Protocol)消息时,通过添加特定的头部信息来增强安全性与认证机制。在这种情况下,标签“TokenSoapHeader”暗示我们可能在...

    RecyclerVeiw的header/footer和下拉示例

    添加Header和Footer的方法主要有两种:一是通过自定义Adapter,二是使用库如`SectionedRecyclerViewAdapter`或`StickyHeaderLayoutManager`。 1. 自定义Adapter添加Header和Footer: - 创建Header和Footer的布局...

    ListView 有Header时下拉刷新

    Header通常被视为ListView的第一项,因此可以在Adapter的初始化阶段添加。 为了实现下拉刷新,我们可以使用SwipeRefreshLayout。SwipeRefreshLayout提供了一个下拉刷新的布局,可以包裹在ListView外部。当用户下拉...

    soapheader的创建和解析

    这可以通过使用JAXB(Java Architecture for XML Binding)来创建XML对象,然后将其添加到SOAP消息中完成。以下是一个示例: ```java import javax.xml.soap.*; public class SOAPClient { public static void ...

    仿网易新闻listview加header图片滚动,上拉下拉刷新.zip

    在Android开发中,"仿网易新闻listview加header图片滚动,上拉下拉刷新"是一个常见的功能需求,它涉及到ListView的自定义、Adapter的使用、Header视图的添加以及手势检测和动画效果的实现。这个项目是针对Android...

    Android高级应用源码-仿网易新闻listview加header图片滚动,上拉下拉刷新.zip

    Header View的实现可以通过在Adapter的getView方法中处理,或者使用addHeaderView方法直接添加。 2. **图片滚动效果**:Header View中的图片能够随着ListView的滚动而滚动,这需要对ListView的滚动事件进行监听,并...

    关于使用xfire创建webservice,并且使用消息头的示例

    3. **配置消息处理器**:在XFire的配置中,定义一个消息处理器(MessageHandler),它会在消息被发送或接收时被调用,用于添加、修改或读取消息头。 4. **注册消息处理器**:将这个消息处理器注册到XFire的处理链中...

    实战HTTP Handler (2) -- 向HTTP 处理程序传递参数 源码

    你可以通过`r.Header`访问它们: ```go func handler(w http.ResponseWriter, r *http.Request) { userAgent := r.Header.Get("User-Agent") // ... } ``` 4. Cookie: Cookie用于存储客户端的状态信息。在HTTP...

    wpf中给 treeview 添加 CheckBox和 ContextMenu

    总结来说,WPF中的`TreeView`可以通过数据绑定和模板来实现复杂的功能,如动态添加带复选框的子节点和右键上下文菜单。通过理解数据绑定、模板以及事件处理,你可以根据需求自定义`TreeView`的行为,提高用户体验。

    WPF ListView控件添加排序功能

    &lt;EventSetter Event="Click" Handler="Header_Click"/&gt; &lt;GridViewColumn DisplayMemberBinding="{Binding Name}" Header="Name"/&gt; &lt;GridViewColumn DisplayMemberBinding="{Binding Age}" Header="Age"/&gt; ...

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

    总结来说,本示例展示了如何利用JAX-WS创建一个Web服务客户端,通过自定义`Handler`来处理SOAP消息,特别是进行认证信息的添加。这个过程对于需要对SOAP请求进行额外处理,如添加安全令牌、实现特定逻辑或验证的场景...

    Go-gofight-APIHandler测试用于GolangRouter框架

    SetHeader("Content-Type", "application/json"). SetBody(`{"key": "value"}`). Run(router, yourTestFunc) ``` `appleboy-gofight-b80bb4a`可能是gofight的一个特定版本或者分支,这表明你可能正在使用特定...

    安卓Android源码——仿网易新闻listview加header图片滚动,上拉下拉刷新.zip

    这种情况下,可以使用AsyncTask或者Retrofit等库来处理网络请求,再通过Handler或RxJava将新数据插入Adapter,更新ListView。 7. **性能优化** 对于包含大量数据的ListView,性能优化是关键。可以通过使用...

    js 使用ajax设置和获取自定义header信息的方法小结

    在这个例子中,我们添加了一个名为`token1`的自定义头,并将其值设为`Chenxizhang`。 #### 1.2 直接在`headers`参数中设置 另一种方式是直接在`$.ajax`的选项对象中设置`headers`属性,如下所示: ```javascript $....

    SOAPHEADER方法增强WebService安全性代码

    本篇文章将深入探讨如何利用SOAP Header来增强Web Service的安全性,并通过具体的代码示例进行说明。 首先,我们需要了解为什么要在SOAP Header中处理安全性。传统的HTTP基础认证或Cookie认证方式可能存在安全隐患...

Global site tag (gtag.js) - Google Analytics