一:首先看下soap请求报文:
<soapenv:Envelope xmlns:soapenv="http://schemas./soap/envelope/" xmlns:web="http://webservice./">
<soapenv:Header>
<m:auth xmlns:m="http://auth.sayHello.HelloWorld2.webservice." soapenv:actor="http://schemas./soap/actor/next" soapenv:mustUnderstand="1">
admin
</m:auth>
</soapenv:Header>
<soapenv:Body>
<web:sayHello>
<arg0>world</arg0>
</web:sayHello>
</soapenv:Body>
</soapenv:Envelope>
二:此请求报文中,Header元素下有个子元素<m:auth>,此子元素添加了属性actor="http://schemas./soap/actor/next",说明下个节点扮演此角色。属性mustUnderstand="1"说明服务端处理此报文时,必须理解这个子元素 <m:auth>.
三:服务端是如何处理header头部的呢,是如何理解子元素 <m:auth>的呢,请看服务端代码
1)web服务HelloWorld2,关联了处理程序连,@HandlerChain(file="handle-chain.xml")
package com.cvicse.webservice;
import javax.jws.HandlerChain;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
@WebService
@SOAPBinding(style=SOAPBinding.Style.DOCUMENT)
//收到请求后的处理链
@HandlerChain(file="handle-chain.xml")
public class HelloWorld2 {
@WebMethod
public String sayHello(String userName)
{
System.out.println("say hello ok");
return "hello" + userName;
}
}
2)处理程序连配置文件handle-chain.xml,此配置文件关联了AuthValidatorHandler处理程序, AuthValidatorHandler相当于拦截器吧,客户端请求sayHello方法前,先去AuthValidatorHandler处理
<?xml version="1.0" encoding="UTF-8"?>
<handler-chains xmlns="http://java./xml/ns/javaee">
<handler-chain>
<handler>
<handler-name>AuthValidatorHandler</handler-name>
<handler-class>com.cvicse.webservice.AuthValidatorHandler</handler-class>
</handler>
</handler-chain>
</handler-chains>
3)处理程序链AuthValidatorHandler,handleMessage方法中主要处理头信息的内容,如果请求中头中的值是admin,则继续请求HelloWorld2中的sayHello方法,否则终止处理。
AuthValidatorHandler的getHeaders()方法是把头信息中必须理解的子元素的Qname放到set中,如果请求中头信息的子元素是必须理解的,则运行环境从这个set集合中查找和头元素一样的Qname,如果查找到,则认为这个头的子元素是被理解的,否则不被理解。
/*
* Copyright (c) InforSuite CVICSE Middleware Co., LTD.
* All rights reserved.
*/
package com.cvicse.webservice;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.Node;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConstants;
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;
/**
* <p> <p>
*
* @date 2013-8-13 <br>
* @author yu_xzhen <br>
* @version 9.0.0 <br>
*
*/
public class AuthValidatorHandler implements SOAPHandler<SOAPMessageContext> {
@Override
public boolean handleMessage(SOAPMessageContext context) {
System.out.println("in to handleMessage");
Boolean response_p = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
System.out.println("response_p=" + response_p);
if (!response_p) {
SOAPMessage msg = context.getMessage();
try {
// 从SOAP信息中取出认证信息
SOAPEnvelope env = msg.getSOAPPart().getEnvelope();
SOAPHeader hdr = env.getHeader();
if (hdr == null)
{
System.out.println("No message header.");
generateSOAPFault(msg, "No message header.");
return false;
}
Iterator it = hdr.extractHeaderElements(SOAPConstants.URI_SOAP_ACTOR_NEXT);
if (it == null || !it.hasNext())
{
System.out.println("No header block for role next.");
generateSOAPFault(msg, "No header block for role next.");
return false;
}
if (it == null || !it.hasNext())
{
System.out.println("No header block for role next.");
generateSOAPFault(msg, "No header block for role next.");
return false;
}
Node next = (Node) it.next();
String value = (next == null) ? null : next.getValue();
if (value == null)
{
System.out.println("No authentication info in header block.");
generateSOAPFault(msg, "No authentication info in header block.");
return false;
}
String auth = value.trim();
return authValite(auth);
} catch (SOAPException e) {
e.printStackTrace();
}
}
return false;
}
@Override
public boolean handleFault(SOAPMessageContext context) {
// TODO Auto-generated method stub
return false;
}
@Override
public void close(MessageContext context) {
// TODO Auto-generated method stub
}
@Override
public Set<QName> getHeaders() {
// TODO Auto-generated method stub
System.out.println("Inside SOAP handler of get Headers");
QName usernameHeader = new QName("http://auth.sayHello.HelloWorld2.webservice.", "auth","m");
HashSet<QName> headers = new HashSet<QName>();
headers.add(usernameHeader);
System.out.println("got Headers: " + headers);
return headers;
}
private boolean authValite(String user) {
if (user == null)
return false;
// 常量Constants类,略,自行补上
if (user.equals("admin")) {
return true;
} else {
return false;
}
}
//生成SOAP错误
private void generateSOAPFault(SOAPMessage msg,String reason){
try {
SOAPBody body=msg.getSOAPBody();
SOAPFault fault=body.getFault();
fault.setFaultString(reason);
throw new SOAPFaultException(fault);
} catch (SOAPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}