J2EE web service開發(fā)(四)soap報頭與處理
SOAPHeaderElement 對象中的屬性決定了接收者怎樣處理消息,可以認為header屬性提供了擴展消息的方法,給出了像身份認證,支付,轉發(fā)消息這樣的相關的事情。JAX-RPC客戶API(占位程序,動態(tài)代理,DII)均沒有提供對SOAP文件頭的支持,SAAJ API提供了支持。所有消息處理程序都必須實現(xiàn)javax.xml.rpc.handler.Handler接口,該接口有一系列的方法用以處理soap消息。javax.xml.rpc.handler.GenericHandler是一個缺省適配器類,創(chuàng)建我們自己的消息處理程序的時候從該類繼承覆寫我們自己感興趣的方法就可以了。但每一個handler必須實現(xiàn) getHeader()方法跟 handleRequest()方法.具體實現(xiàn):
服務類HandlerServic:
- package handler;
- public class HandlerService implements HandlerServiceInterface1 {
- public void testInOutHeader(String bodyMsg, String headerMsg)
- {
- System.out.print("testInHeader: " + bodyMsg + "," + headerMsg);
- }
- }
消息處理類:
- package handler;
- import javax.xml.rpc.handler.*;
- import javax.xml.soap.*;
- import javax.xml.namespace.QName;
- import javax.xml.rpc.JAXRPCException;
- import javax.xml.rpc.handler.soap.SOAPMessageContext;
- import java.util.Iterator;
- public class CutomerHandler extends GenericHandler {
- protected QName[] headers = new QName[] {
- new QName("http://handler", "headerMsg")
- };
- public QName[] getHeaders() {
- return headers;
- }// 返回handler要處理的文件頭元素名的素組.
- // 處理接收到的soap消息.如果返回值為false時JAX-RPC會立即中斷對SOAP消息處理并將soap消息回傳。關于saaj api使用方法見j2ee web service開發(fā)(三)
- public boolean handleRequest(MessageContext msgContext) {
- try {
- SOAPMessage soapMessage = ((SOAPMessageContext) msgContext).
- getMessage();
- SOAPHeader soapHeader = soapMessage.getSOAPHeader();
- Iterator it = soapHeader.extractAllHeaderElements();
- while (it.hasNext()) {
- SOAPHeaderElement headerElement = (SOAPHeaderElement) it.next();
- Name headerName = headerElement.getElementName();
- System.out.println(" header name is: " +
- headerName.getQualifiedName());
- System.out.println(" header value is: " +
- headerElement.getValue());
- }
- SOAPBody soapBody = soapMessage.getSOAPBody();
- Iterator bodyIterator = soapBody.getChildElements();
- while (bodyIterator.hasNext()) {
- SOAPBodyElement soapBodyElement = (SOAPBodyElement)
- bodyIterator.next();
- System.out.println("soapBodyElement print: " +
- soapBodyElement.getNodeName());
- }
- SOAPBodyElement nextSoapBodyElement = (SOAPBodyElement) soapBody.
- getChildElements().next();
- SOAPElement soapElement = (SOAPElement) nextSoapBodyElement.
- getChildElements().next();
- System.out.println("soapElement print: " + soapElement.getLocalName() +
- " " + soapElement.getValue());
- } catch (SOAPException e) {
- throw new JAXRPCException(e);
- }
- return true;
- }
- // 返回soap應答消息,本例修改soap文件頭的值再返傳給客戶端.
- public boolean handleResponse(MessageContext msgContext) {
- try {
- SOAPMessage soapMessage = ((SOAPMessageContext) msgContext).
- getMessage();
- SOAPHeader soapHeader = soapMessage.getSOAPHeader();
- SOAPBody soapBody = soapMessage.getSOAPBody();
- SOAPBodyElement soapBodyElement = (SOAPBodyElement) soapBody.
- getChildElements().next();
- String rpcName = soapBodyElement.getElementName().getLocalName();
- SOAPFactory soapFactory = SOAPFactory.newInstance();
- Name headerName = soapFactory.createName("headerMsg", "ns","http://handler");
- SOAPHeaderElement she = soapHeader.addHeaderElement(headerName);
- she.setValue("return header message");
- } catch (SOAPException e) {
- throw new JAXRPCException(e);
- }
- return true;
- }
- }
用于生成布署描述符的WSTOOLS工具的配置文件:
- < configuration xmlns="http://www.jboss.org/jbossws-tools"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.jboss.org/jbossws-tools http://www.jboss.org/jbossws-tools/schema/jbossws-tool_1_0.xsd">
- < java-wsdl>
- < service name="TestService" style="rpc" endpoint="handler.HandlerServiceInterface1">
- < operation name="testInOutHeader">
- < parameter type="java.lang.String"/>
- < parameter type="java.lang.String"/>
- < /operation>
- < /service>
- < namespaces target-namespace="http://handler" type-namespace="http://handler"/>
- < mapping file="HandlerServiceInterface1.xml"/>
- < webservices servlet-link="HandlerServiceInterface1"/>
- < /java-wsdl>
- < /configuration>
關于wstools工具的使用見j2ee web service開發(fā)(一).
在生成的webservice描述符文件中手工加入以下代碼:
- < handler>
- < handler-name>CutomerHandler< /handler-name>
- < handler-class>handler.CutomerHandler< /handler-class>
- /handler>
用以配置處理soap消息頭的類.
客戶端代碼:利用j2ee web serive開發(fā)(三)介紹的api不難寫出saaj客戶端代碼就不再重復勞動了。這里只介紹JBOss ws利用DII實現(xiàn)soap消息頭的處理,它擴展了標準jax-rpc api.
- package handler;
- import javax.xml.namespace.QName;
- import javax.xml.rpc.Call;
- import javax.xml.rpc.ParameterMode;
- import javax.xml.rpc.Service;
- import org.jboss.ws.Constants;
- import org.jboss.ws.jaxrpc.CallImpl;
- import javax.xml.rpc.ServiceFactory;
- import java.util.*;
- public class HandlerClient {
- public HandlerClient() {
- }
- public static void main(String[] args) throws Exception{
- HandlerClient handlerclient = new HandlerClient();
- handlerclient.testUnboundInOutHeader();
- }
- public void testUnboundInOutHeader() throws Exception{
- Service service = ServiceFactory.newInstance().createService(new QName("TestService"));
- CallImpl call = (CallImpl)service.createCall();
- call.setOperationName(new QName("http://handler", "testInOutHeader"));
- call.addParameter("String_1", Constants.TYPE_LITERAL_STRING, ParameterMode.IN);
- call.addParameter("String_2", Constants.TYPE_LITERAL_STRING, ParameterMode.IN);
- call.setTargetEndpointAddress("http://hechang:8082/customer-handler/services/HandlerServiceInterface1");
- QName xmlName = new QName("http://handler", "headerMsg");
- // xmlName = new QName("http://otherns", "HeaderValue");
- call.addUnboundHeader(xmlName, Constants.TYPE_LITERAL_STRING, String.class, ParameterMode.IN);
- call.setUnboundHeaderValue(xmlName, " IN header message");
- // 設置消息頭 可以設定多組
- Object retObj = call.invoke(new Object[]{"Hello world!", "IN header message"});
- String unboundRet = (String)call.getUnboundHeaderValue(xmlName);
- // 處理返回的消息頭的值
- System.out.println(" unboundReturn: "+unboundRet);
- }
- }
以上,J2EE Web Service開發(fā)中的soap報頭與處理也完成了。
【編輯推薦】