1、消息头定义
一般soap消息中,消息体是携带消息的核心内容;消息头中的字段,多数用于校验。定义消息头,就相当于定义一个bean对象。本例中,在上一篇的继承上,为消息增加消息头,其中消息头核心内容包括三个字段:serviceId,servPassWord和timeStamp。源代码如下:
1
|
<br>
|
package com.yht.msg.header;
- /**
/**
* 定义消息头中包含哪些内容的bean。 * @author Administrator * */ public class AttachHeader { /** * 消息节点标签。 */ public static final String NODEFLAG = "tns"; /** * 消息头标签。 */ public static final String HEADFLAG = "RequestHeader"; /** * 命名空间。 */ public static final String NAMESPACE = "http://com.yht.msg"; /** * 时间戳标签。 */ public static final String TIMESTAMP = "timeStamp"; /** * 业务编号标签。 */ public static final String SERVICEID = "serviceId"; /** * 业务对于的校验密码标签。 */ public static final String SERVPASSWORD = "servPassWord"; /** * 时间戳。 */ private String timeStamp; /** * 业务编号。 */ private String serviceId; /** * 业务对于的校验密码。 */ private String servPassWord; /** * 获取时间戳。 * @return 时间戳。 */ public String getTimeStamp() { return timeStamp; } /** * 设置时间戳。 * @param timeStamp 时间戳。 */ public void setTimeStamp(String timeStamp) { this.timeStamp = timeStamp; } /** * 获取业务编号。 * @return 业务编号。 */ public String getServiceId() { return serviceId; } /** * 设置业务编号。 * @param serviceId 业务编号。 */ public void setServiceId(String serviceId) { this.serviceId = serviceId; } /** * 获取校验密码。 * @return 校验密码。 */ public String getServPassWord() { return servPassWord; } /** * 设置校验密码。 * @param servPassWord 校验密码。 */ public void setServPassWord(String servPassWord) { this.servPassWord = servPassWord; } }2、打包与解析消息头方法
消息头中字段定义好了,那么对于demo作为:客户端,发送出去的消息携带消息头,需要一个大包消息头的方法;服务端,接受别处来的消息,需要一个解析消息头的方法。这重新定义一个类:DealHeader继承消息头定义的类AttachHeader。该类中,有两个方法:packSoapHeader和parseSoapHeader。源代码如下:
-
package com.yht.msg.header;
-
-
import java.util.Iterator;
-
-
import org.apache.axiom.om.OMAbstractFactory;
-
import org.apache.axiom.om.OMElement;
-
import org.apache.axiom.om.OMFactory;
-
import org.apache.axiom.om.OMNamespace;
-
import org.apache.axiom.soap.SOAPFactory;
-
import org.apache.axiom.soap.SOAPHeader;
-
import org.apache.axiom.soap.SOAPHeaderBlock;
-
import org.apache.axis2.client.ServiceClient;
-
-
/**
-
* 提供上下行消息中,处理消息头的方法。
-
* 作为服务端,需要解析消息中的消息头;作为客户端,需要在消息头中加入消息头。
-
* @author Administrator
-
*
-
*/
-
public class DealHeader extends AttachHeader
-
{
-
/**
-
* 打包消息头。将设置到AttachHeader中的各字段的内容,打包到消息中发送出去。
-
* @param serviceClient
-
*/
-
public void packSoapHeader(ServiceClient serviceClient)
-
{
-
//获取创建工厂。
-
OMFactory oMFactory = OMAbstractFactory.getOMFactory();
-
SOAPFactory sOAPFactory = OMAbstractFactory.getSOAP11Factory();
-
-
//利用工厂,创建命名空间和消息头。
-
OMNamespace oMNamespace = oMFactory.createOMNamespace(NAMESPACE, NODEFLAG);
-
SOAPHeaderBlock soapHeader =
-
sOAPFactory.createSOAPHeaderBlock(HEADFLAG, oMNamespace);
-
-
//消息头中的时间错节点。
-
String timeStamp = (getTimeStamp() == null) ? "" : getTimeStamp();
-
SOAPHeaderBlock timeBlock =
-
sOAPFactory.createSOAPHeaderBlock(TIMESTAMP, oMNamespace);
-
timeBlock.addChild(sOAPFactory.createOMText(timeStamp));
-
-
//消息头中的业务表示节点。
-
String serviceId = (getServiceId() == null) ? "" : getServiceId();
-
SOAPHeaderBlock serviceIdBlock =
-
sOAPFactory.createSOAPHeaderBlock(SERVICEID, oMNamespace);
-
serviceIdBlock.addChild(sOAPFactory.createOMText(serviceId));
-
-
//消息头中的业务校验密码节点。
-
String servPassWord = (getServPassWord() == null) ? "" : getServPassWord();
-
SOAPHeaderBlock servPassWordBlock =
-
sOAPFactory.createSOAPHeaderBlock(SERVPASSWORD, oMNamespace);
-
servPassWordBlock.addChild(sOAPFactory.createOMText(servPassWord));
-
-
//将各个节点加入到消息头中。
-
soapHeader.addChild(serviceIdBlock);
-
soapHeader.addChild(servPassWordBlock);
-
soapHeader.addChild(timeBlock);
-
-
//将消息头加入到当前消息中。
-
serviceClient.addHeader(soapHeader);
-
}
-
-
/**
-
* 解析消息头。作为服务端接受消息时,将当前消息中的消息头取出,单独解析成AttachHeader中设定的字段的值。
-
* @param soapHeader
-
*/
-
public void parseSoapHeader(SOAPHeader soapHeader)
-
{
-
//消息头非空判断。
-
if(soapHeader == null)
-
{
-
return ;
-
}
-
-
//获取消息流中的消息头列表,并做非空判断。
-
Iterator<?> headerList = soapHeader.examineHeaderBlocks(null);
-
if(headerList == null)
-
{
-
return ;
-
}
-
-
//获取第一个消息头,并获取消息头中的元素。
-
SOAPHeaderBlock header = (SOAPHeaderBlock)headerList.next();
-
Iterator<?> elementList = header.getChildElements();
-
-
OMElement element = null;
-
String key = null;
-
String value = null;
-
if(elementList != null)
-
{
-
//解析非空列表中的所有节点。
-
while(elementList.hasNext())
-
{
-
//获取节点key和value值。
-
element = (OMElement)elementList.next();
-
key = element.getLocalName();
-
value = element.getText().trim();
-
-
//如果是业务标签,将值设置。
-
if(SERVICEID.equals(key))
-
{
-
setServiceId(value);
-
}
-
-
//如果是校验密码,将值设置。
-
if(SERVPASSWORD.equals(key))
-
{
-
setServPassWord(value);
-
}
-
-
//如果是时间戳,将值设置。
-
if(TIMESTAMP.equals(key))
-
{
-
setTimeStamp(value);
-
}
-
}
-
}
-
}
-
}
3、客户端服务端携带消息头
客户端大包消息头和服务端解析消息头的方法都定义好了,那么如何大包解析呢?
(1)客户端
对于上篇中封装的客户端类SendAttachClient,要实现打包需要做如下步骤:
一、SendAttachClient继承DealHeader。
二、根据服务地址,创建一个发送消息的客户端时,打包消息头。如下代码:
-
//1、根据服务地址,创建一个发送消息的客户端。
-
1
<br>
-
try
-
{
-
stub = new SendAttachServiceStub(serviceAddress);
-
packSoapHeader(stub._getServiceClient());
-
}
-
catch (AxisFault e1)
-
{
-
// TODO Auto-generated catch block
-
e1.printStackTrace();
-
}
三、测试代码,增加设置消息头字段的代码。源代码如下:
-
package main;
-
1
<br>
-
-
import java.text.SimpleDateFormat;
-
import java.util.Calendar;
-
-
import com.yht.msg.client.SendAttachClient;
-
-
/**
-
* 客户端测试类。
-
* @author Administrator
-
*
-
*/
-
public class Test
-
{
-
/**
-
* 入口方法。
-
* @param args
-
*/
-
public static void main(String[] args)
-
{
-
//获取系统时间,为日历对象。
-
Calendar calendar = Calendar.getInstance();
-
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
-
String time = simpleDateFormat.format(calendar.getTime());
-
-
String result = null;
-
String subject = "Hello Axis2-1.6.2!";
-
String serviceAddress = "http://127.0.0.1:8088/SendAttachService";
-
String serviceId = "12345";
-
String servPassWord = "54321";
-
String timeStamp = time;
-
-
//创建客户端类。
-
SendAttachClient client = new SendAttachClient();
-
-
client.setServiceId(serviceId);
-
client.setServPassWord(servPassWord);
-
client.setTimeStamp(timeStamp);
-
-
//设置消息体内容。
-
client.setSubject(subject);
-
-
//设置服务地址。
-
client.setServiceAddress(serviceAddress);
-
-
//发送消息获取,结果。
-
result = client.sendAttach();
-
-
//打印结果。
-
System.out.println(result);
-
}
-
}
(2)服务端
作为服务端,只要获取当前消息中的消息头;new一个打包消息的类对象,将消息头放到对象中解析;消息中的值就消息到该对象中。对于上一篇中的服务端类GetAttachService,增加解析消息头能力后,源代码如下:
1
|
<br>
|
-
package com.yht.msg.service;
-
-
import org.apache.axiom.soap.SOAPHeader;
-
import org.apache.axis2.context.MessageContext;
-
-
import com.yht.msg.SendAttach;
-
import com.yht.msg.SendAttachResponse;
-
import com.yht.msg.SendAttachServiceSkeletonInterface;
-
import com.yht.msg.header.DealHeader;
-
-
/**
-
* 服务端,接受消息。
-
* @author Administrator
-
*
-
*/
-
public class GetAttachService
-
implements SendAttachServiceSkeletonInterface
-
{
-
/**
-
* 接受消息并返回相应的相应。
-
*/
-
public SendAttachResponse sendAttach(SendAttach arg0)
-
{
-
//获取上下行消息中的消息头。
-
MessageContext context = MessageContext.getCurrentMessageContext();
-
SOAPHeader soapHeader = context.getEnvelope().getHeader();
-
-
//解析消息头。
-
DealHeader dealHeader = new DealHeader();
-
dealHeader.parseSoapHeader(soapHeader);
-
-
// TODO Auto-generated method stub
-
System.out.println(dealHeader.getServiceId());
-
System.out.println(dealHeader.getServPassWord());
-
System.out.println(dealHeader.getTimeStamp());
-
System.out.println(arg0.getArgs0());
-
-
//响应。
-
SendAttachResponse response = new SendAttachResponse();
-
response.set_return("success");
-
return response;
-
}
-
-
}