分享
 
 
 

处理链处理WEB服务中的请求/响应消息

王朝other·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

为什么使用处理链?

一个处理程序可以在客户端或服务器端用来创建一个SOAP的请求消息和响应消息。例如一个使用消息处理程序的简单例子,在SOAP消息中的实体部分对数据进行加密和解密,客户端在他向WEB服务发送SOAP请求消息前必须使用消息处理程序对消息进行加密,WEB服务收到请求后,在它将数据发送到后台实现WEB服务之前,必须使用消息处理程序对从客户端发送过来的消息进行解密。与请求消息的传输方向相反,SOAP响应消息也要执行相同的步骤。

另外一个例子,在SOAP消息的头部分访问信息进行处理。SOAP头经常用来存储WEB服务具体说明信息并且使用消息处理程序来操作它。例如将用户名和密码可以放在SOAP消息的头部分中来发送到验证处理程序。

SOAP消息处理可以用来提高WEB服务的使用效率。这种方法的实现可以通过使用队列缓冲SOAP响应的次序。处理程序可以使SOAP的请求信息生效并且将消息交互纪录下来。

处理链:

处理链就是将每一个消息处理装配成一个链表形式进行处理。在WEB服务中实现可能需要调用多个处理类,用来提供处理请求/响应前面或后面的服务。JAX-RPC运行环境中可以在链表中调用多个处理类。这种处理消息的概念称为处理链。

处理链模型:

一个消息处理类功能主要在客户服务器端通信中,尽可能的为终端服务和可以设置用来截取SOAP消息并且在以下几种情况下对消息执行各种操作:

1)在客户端,在SOAP请求被建立后并且在发送到WEB服务之前

2)在WEB服务端,在SOAP消息请求被WEB服务程序处理之前

3)在WEB服务端,在WEB服务发送SOAP消息响应之前

4)在客户端,在JAX-RPC运行时处理从WEB服务中收到的SOAP响应之前

消息处理链可以使用后台组件也可以不使用,下面主要针对各种处理情况?

(图1)

图一描述了使用后台组件进行处理链操作。当客户端调用WEB服务时,SOAP请求到达处理链中的处理请求部分,一旦处理通过,处理程序将消息传送到WEB服务中并且执行。处理响应程序被WEB服务调用并且将SOAP响应发送到客户端。

图2使用后台组件的处理链模型

举例:

这个例子我们采用的服务为WEBLOGIC8.X,这里我们通过后台组件提供查询服务的验证处理程序来具体说明。这里面的验证内容主要是帐号和个人识别码,它们被放在SOAP请求消息的头部分中,消息处理程序将重新获得帐号和个人识别码并验证,假如验证通过,一旦通过验证,后台组件将会调用余额查询来获得此帐号的余额。

以下就是写一个处理程序的步骤:

1)处理程序必须实现javax.xml.rpc.handler.Handler 接口或继续Weblogic中的GenericHandler 类。

2)javax.xml.rpc.handler.Handler 接口包含了以下这些方法用来实现

init ()

destroy()

getHeaders()

handleRequest()

handleResponse()

handleFault()

假如使用weblogic.webservice.GenericHandler 类,只需要重写必须的方法,

在这个例子中验证处理程序重写了handleRequest() 和handleResponse() 方法。

假如handleRequest()方法返回true,将会调用处理链中的下一个处理程序,

假如这个处理程序是处理链中最后一个元素,将会调用后台的WEB服务程序。

假如 handleRequest()方法返回false,对应的handleResponse()方法将会被调用。

验证处理程序中handleRequest() 将从SOAP的头部分中重新获得帐号和个人识别码,

并且验证后要返回true 或false结果。

AuthenticationHandler.java

import java.util.Map;

import java.util.Iterator;

import javax.xml.rpc.JAXRPCException;

import javax.xml.rpc.handler.soap.SOAPMessageContext;

import javax.xml.rpc.handler.HandlerInfo;

import javax.xml.rpc.handler.MessageContext;

import javax.xml.namespace.QName;

import javax.xml.soap.*;

import weblogic.webservice.GenericHandler;

public class AuthenticationHandler extends GenericHandler

{

PRivate int me = System.identityHashCode(this);

private HandlerInfo handlerInfo = null;

String accountNo = null;

String pin = null;

public void init(HandlerInfo handlerInfo)

{

this.handlerInfo = handlerInfo;

}

public boolean handleRequest(MessageContext messageContext)

{

System.err.println("** handleRequest called in: "+me);

try

{

SOAPMessageContext sctx = (SOAPMessageContext)messageContext;

SOAPMessage message = sctx.getMessage();

SOAPPart sp = message.getSOAPPart();

SOAPEnvelope senv = sp.getEnvelope();

SOAPHeader sh = senv.getHeader();

Iterator iter = sh.getChildElements();

if(iter.hasNext())

{

iter.next(); //skip text

Object obj = iter.next(); //account details

SOAPElement elt = (SOAPElement)obj;

iter = elt.getChildElements();

iter.next(); //skip text node

obj = iter.next();

elt = (SOAPElement)obj;

accountNo = elt.getValue();

iter.next(); //skip text node

obj = iter.next();

elt = (SOAPElement)obj;

pin = elt.getValue();

}

}

catch (Exception e)

{

e.printStackTrace();

throw new JAXRPCException(e);

}

if(accountNo.equals("12345") && pin.equals("6789"))

return true;

else

return false;

}

public boolean handleResponse(MessageContext messageContext)

{

System.out.println("Inside HandleResponse");

return true;

}

public QName[] getHeaders()

{

return handlerInfo.getHeaders();

}

}

以下就是余额查询的代码,是一个非常简单的服务返回给出已知帐号的余额。

BalanceEnquiryService.java

public class BalanceEnquiryService

{

public float getBalance(String accountNo)

{

if(accountNo.equals("12345"))

return 5000f;

else

return 100f;

}

}

WEB服务中的web-service.xml 必须要修改为包含处理链的描述,下面几个部分需要在web-service.xml 中修改的:

1)在 的根元素中创建一个 子元素,在这个子元素中包含了WEB服务中一系列处理链程序的定义。

2)创建的子元素 ,在这个子元素中,显示了所有处理链中的处理程序。对于每一个处理程序,使用类名必须指定 java类的全限定名以便实现处理程序。使用元素来指定处理程序的初始化参数。

3.使用(它本身是 的子元素)的子元素元素,来具体说明处理链是WEB服务中的一个操作。

注重:处理链只是自执行的,没有后台组件参与执行,在这中情况下,只要使用处理链属性中的元素并且并不需要指定组件或方法的属性,就像下面所选其中的一部分:

OperaTION name="chainService"

handler-chain="myChain" />

这里有一个完整的WEB.xml的例子:

web-service.xml

uri="/BalanceEnquiryService"

targetNamespace="http://www.bea.com">

class-name="BalanceEnquiryService">

handler-chain="AuthenticationHandlerChain"

component="jccomp0">

style="in" type="xsd:string" />

class-name="java.lang.Float"

type="xsd:float" />

这里面处理链的名字叫做AuthenticationHandlerChain,

这里面包含了一个AuthenticationHandler处理程序,注重,

在操作中包含了操作属性handler-chain="AuthenticationHandlerChain".

这里给出了ant脚本build.xml用来打包EAR,注重在打包之前必须有Web.xml 和 application.xml

build.xml

BalanceEnquiryService.java" srcdir="${source}" destdir="${build}/WEB-INF/classes" />

ant脚本在创建WAR文件的同时也进行EAR打包,在WEBLOGIC服务器上部署打包好的EAR文件,

下面是客户端调用余额查询的程序:

Client.java

import org.apache.axis.client.Call;

import org.apache.axis.client.ServiceFactory;

import org.apache.axis.client.Service;

import org.apache.axis.MessageContext;

import org.apache.axis.attachments.Attachments;

import org.apache.axis.message.SOAPEnvelope;

import javax.xml.namespace.QName;

import javax.xml.soap.SOAPBody;

import javax.xml.soap.SOAPBodyElement;

import javax.xml.soap.SOAPConnection;

import javax.xml.soap.SOAPConnectionFactory;

import javax.xml.soap.SOAPElement;

import javax.xml.soap.SOAPHeader;

import javax.xml.soap.SOAPHeaderElement;

import javax.xml.soap.SOAPMessage;

import javax.xml.soap.SOAPPart;

import javax.xml.namespace.QName;

import javax.xml.rpc.ParameterMode;

import javax.xml.soap.AttachmentPart;

import javax.xml.soap.MessageFactory;

import javax.xml.soap.Name;

import javax.xml.rpc.ParameterMode;

import java.net.URL;

import java.util.Iterator;

public class Client

{

private static String TARGET_NAMESPACE = "http://www.bea.com";

private static QName xsdFloat = new

QName("http://www.w3.org/2001/XMLSchema", "float");

public static org.apache.axis.message.SOAPEnvelope env = null;

public static SOAPMessage message = null;

public static void main(String[] argv) throws Exception

{

Client client = new Client();

env = client.constrUCtSOAPEnvelope();

client.constructHeader(env);

client.constructBody(env);

System.setProperty( "javax.xml.rpc.ServiceFactory",

"org.apache.axis.client.ServiceFactory" );

String url =

"http://localhost:7001/BalanceEnquiry/BalanceEnquiryService";

ServiceFactory factory =

(org.apache.axis.client.ServiceFactory)ServiceFactory.

newInstance();

QName serviceName = new QName(TARGET_NAMESPACE,

"BalanceEnquiryService");

Service service =

(org.apache.axis.client.Service)factory.

createService(serviceName);

Call call = (org.apache.axis.client.Call)service.createCall();

call.setTargetEndpointAddress(url);

SOAPEnvelope result = call.invoke(env);

System.out.println(result);

}

public SOAPEnvelope constructSOAPEnvelope() throws Exception

{

org.apache.axis.message.SOAPEnvelope env = new

org.apache.axis.message.SOAPEnvelope();

return env;

}

public void constructHeader(SOAPEnvelope envelope) throws Exception

{

SOAPHeader header = envelope.getHeader();

Name headerElementName =

envelope.createName("AccountDetails","",

"http://schemas.xmlsoap.org/soap/

envelope/");

SOAPHeaderElement headerElement =

header.addHeaderElement(headerElementName);

headerElement.setMustUnderstand(false);

headerElement.addNamespaceDeclaration("soap",

"http://schemas.xmlsoap.org/soap/envelope/");

SOAPElement accNo = headerElement.addChildElement("accountNo");

accNo.addTextNode("12345");

SOAPElement pinNo = headerElement.addChildElement("pin");

pinNo.addTextNode("6789");

}

public void constructBody(SOAPEnvelope envelope) throws Exception

{

SOAPBody body = envelope.getBody();

Name bodyRootElementName =

envelope.createName("getBalance","",

"http://schemas.xmlsoap.org/soap/

encoding/");

SOAPBodyElement bodyRootElement =

body.addBodyElement(bodyRootElementName);

SOAPElement bodyElement =

bodyRootElement.addChildElement("param0");

bodyElement.addAttribute(envelope.createName("xsi:type"),

"xsd:string");

bodyElement.addTextNode("12");

}

}

假如在客户端也有一个处理程序,以下部分要发生变化:

(1)导入import javax.xml.rpc.handler.HandlerInfo;

import javax.xml.rpc.handler.HandlerRegistry;两个类。

(2)在call().invoke前面加:

QName portName = new QName( "http://bea.com/",

"HelloWorldServicePort");

HandlerRegistry registry = service.getHandlerRegistry();

List handlerList = new ArrayList();

handlerList.add( new HandlerInfo( ClientHandler.class, null,null ) );

registry.setHandlerChain( portName, handlerList );

结论:

我们希望能让大家更多的了解关于处理链机制并且应用到WEB服务中。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有