使用JAX-RPC、Handler开发web service例子
Handler的基本概念
J2EE Web 服务中的Handler技术特点非常像Servlet技术中的Filter。我们知道,在Servlet中,当一个HTTP到达服务端时,往往要经过多个Filter对请求进行过滤,然后才到达提供服务的Servlet,这些Filter的功能往往是对请求进行统一编码,对用户进行认证,把用户的访问写入系统日志等。相应的,Web服务中的Handler通常也提供一下的功能:
对客户端进行认证、授权;
把用户的访问写入系统日志;
对请求的SOAP消息进行加密,解密;
为Web Services对象做缓存。
SOAP消息Handler能够访问代表RPC请求或者响应的SOAP消息。在JAX-RPC技术中,SOAP消息Handler可以部署在服务端,也可以在客户端使用。
Handler的基本概念原文出自
www-128.ibm.com/developerworks/cn/webservices/ws-handler/index.html
下面我们来看一个典型的SOAP消息Handler处理顺序:
某个在线支付服务需要防止非授权的用户访问或者撰改服务端和客户端传输的信息,从而使用消息摘要(Message Digest)的方法对请求和响应的SOAP消息进行加密。当客户端发送SOAP消⑹保突Ф说腍andler把请求消息中的某些敏感的信息(如信用卡密码)进行加密,然后把加密后的SOAP消息传输到服务端;服务端的SOAP消息Handler截取客户端的请求,把请求的SOAP 消息进行解密,然后把解密后的SOAP消息派发到目标的Web服务端点。
JAX-RPC,Java API for XMLbased RPC,顾名思义,它是一种远程方法调用(或者说远程过程调用),那么它和其它的远程方法调用(RPC, COM,CORBA,RMI)有什么区别呢?
综合比较常用的远程方法调用技术,它们有以下的共性:
在客户端和服务端有通用编程接口;
在客户端有Stub,在服务端有Tie(有的叫Skeleton);
客户端和服务端有专门的协议进行数据传输。
对于通用接口的描述,比如CORBA有IDL of CORBA,Java RMI有Java RMI interface in RMI,对于XMLbased RPC来说,IDL就是WSDL(Web服务描述语言)。那么XMLbased RPC来说,什么是这个结构中的"传输协议",当然是SOAP,SOAP消息通过以传输文本为基础的协议(HTTP、SMTP、FTP)为载体来使用的,也就是说,SOAP消息的传输建立在HTTP、SMTP、FTP传输协议之上。
客户端通过SOAP消息和JAX-RPC服务端交互,JAX-RPC服务端运行在Servlet容器中,它通过调用EJB容器中的EJB组件来处理具体的业务逻辑。
使用JAX-RPC开发Web服务,可以按照以下的步骤进行:
1. 服务端点定义;
2. 服务描述;
3. 服务端点实现;
4. 服务端点部署;
5. 服务发布和发现。
下面使用JAX-RPC、Handler开发web service例子
运行环境:eclipse 插件wtp开发web service
1 最简单的Web服务
package com;
public interface Hello extends java.rmi.Remote {
public java.lang.String sayHello(java.lang.String string1) throws java.rmi.RemoteException;
}
接口实现文件
package com;
public class HelloBindingImpl implements com.Hello {
public java.lang.String sayHello(java.lang.String name) throws java.rmi.RemoteException {
return "A dynamic proxy hello to " + name + "!";
}
}
package com;
客户端handler
public class ClientHandler implements javax.xml.rpc.handler.Handler {
public ClientHandler() {
}
public boolean handleRequest(javax.xml.rpc.handler.MessageContext context) {
System.out.println("ClientHandler: In handleRequest");
return true;
}
public boolean handleResponse(javax.xml.rpc.handler.MessageContext context) {
System.out.println("ClientHandler: In handleResponse");
return true;
}
public boolean handleFault(javax.xml.rpc.handler.MessageContext context) {
System.out.println("ClientHandler: In handleFault");
return true;
}
public void init(javax.xml.rpc.handler.HandlerInfo config) {
}
public void destroy() {
}
public javax.xml.namespace.QName[] getHeaders() {
return null;
}
}
服务器端handler
package com;
public class ServerHandler implements javax.xml.rpc.handler.Handler {
public ServerHandler() {
}
public boolean handleRequest(javax.xml.rpc.handler.MessageContext context) {
System.out.println("ServerHandler: In handleRequest");
return true;
}
public boolean handleResponse(javax.xml.rpc.handler.MessageContext context) {
System.out.println("ServerHandler: In handleResponse");
return true;
}
public boolean handleFault(javax.xml.rpc.handler.MessageContext context) {
System.out.println("ServerHandler: In handleFault");
return true;
}
public void init(javax.xml.rpc.handler.HandlerInfo config) {
}
public void destroy() {
}
public javax.xml.namespace.QName[] getHeaders() {
return null;
}
}
2.服务描述和服务端点实现;
创建web service后自动生成HelloBindingImpl.wsdl文件和服务端点实现文件
3.服务端点部署
在server-config的service标签中添加
<requestFlow>
<handler type="java:org.apache.axis.handlers.JAXRPCHandler">
<parameter name="scope" value="session"/>
<parameter name="className" value="com.ClientHandler"/>
</handler>
<handler type="java:org.apache.axis.handlers.JAXRPCHandler">
<parameter name="scope" value="session"/>
<parameter name="className" value="com.ServerHandler"/>
</handler>
</requestFlow>
<responseFlow>
<handler type="java:org.apache.axis.handlers.JAXRPCHandler">
<parameter name="scope" value="session"/>
<parameter name="className" value="com.ServerHandler"/>
</handler>
<handler type="java:org.apache.axis.handlers.JAXRPCHandler">
<parameter name="scope" value="session"/>
<parameter name="className" value="com.ClientHandler"/>
</handler>
</responseFlow>
客户端调用方法
package com;
import javax.xml.namespace.QName;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceFactory;
import java.net.URL;
public class HelloClient {
public static void main(String[] args) throws Exception {
String UrlString = "http://localhost:8080/WSHandler/services/HelloBindingImpl?wsdl";
//http://localhost:8080/WSHandler/services/HelloBindingImpl
String nameSpaceUri = "http://com";
String serviceName = "HelloBindingImplService";
String portName = "HelloBindingImpl";
//调用的web服务的url地址,这里是一个http请求,希望得到的结果是wsdl文档。
URL helloWsdlUrl = new URL(UrlString);
ServiceFactory serviceFactory = ServiceFactory.newInstance();
Service helloService = serviceFactory.createService(helloWsdlUrl,new QName(nameSpaceUri, serviceName));
java.util.List list = helloService.getHandlerRegistry().getHandlerChain(new QName(nameSpaceUri, portName));
list.add(new javax.xml.rpc.handler.HandlerInfo(ClientHandler.class,null,null));
// 为对象获得动态代理
//传入getPort()方法的是一个接口定义,它将被用作在运行时创建动态代理的模版
Hello myProxy = (Hello) helloService.getPort(new QName("HelloBindingImplService", portName),com.Hello.class);
//使用java.lang.reflect.InvocationHandler.Invoke()调用服务
System.out.println(myProxy.sayHello("Buzz"));
}
}
Handler的基本概念
J2EE Web 服务中的Handler技术特点非常像Servlet技术中的Filter。我们知道,在Servlet中,当一个HTTP到达服务端时,往往要经过多个Filter对请求进行过滤,然后才到达提供服务的Servlet,这些Filter的功能往往是对请求进行统一编码,对用户进行认证,把用户的访问写入系统日志等。相应的,Web服务中的Handler通常也提供一下的功能:
对客户端进行认证、授权;
把用户的访问写入系统日志;
对请求的SOAP消息进行加密,解密;
为Web Services对象做缓存。
SOAP消息Handler能够访问代表RPC请求或者响应的SOAP消息。在JAX-RPC技术中,SOAP消息Handler可以部署在服务端,也可以在客户端使用。
Handler的基本概念原文出自
www-128.ibm.com/developerworks/cn/webservices/ws-handler/index.html
下面我们来看一个典型的SOAP消息Handler处理顺序:
某个在线支付服务需要防止非授权的用户访问或者撰改服务端和客户端传输的信息,从而使用消息摘要(Message Digest)的方法对请求和响应的SOAP消息进行加密。当客户端发送SOAP消⑹保突Ф说腍andler把请求消息中的某些敏感的信息(如信用卡密码)进行加密,然后把加密后的SOAP消息传输到服务端;服务端的SOAP消息Handler截取客户端的请求,把请求的SOAP 消息进行解密,然后把解密后的SOAP消息派发到目标的Web服务端点。
JAX-RPC,Java API for XMLbased RPC,顾名思义,它是一种远程方法调用(或者说远程过程调用),那么它和其它的远程方法调用(RPC, COM,CORBA,RMI)有什么区别呢?
综合比较常用的远程方法调用技术,它们有以下的共性:
在客户端和服务端有通用编程接口;
在客户端有Stub,在服务端有Tie(有的叫Skeleton);
客户端和服务端有专门的协议进行数据传输。
对于通用接口的描述,比如CORBA有IDL of CORBA,Java RMI有Java RMI interface in RMI,对于XMLbased RPC来说,IDL就是WSDL(Web服务描述语言)。那么XMLbased RPC来说,什么是这个结构中的"传输协议",当然是SOAP,SOAP消息通过以传输文本为基础的协议(HTTP、SMTP、FTP)为载体来使用的,也就是说,SOAP消息的传输建立在HTTP、SMTP、FTP传输协议之上。
客户端通过SOAP消息和JAX-RPC服务端交互,JAX-RPC服务端运行在Servlet容器中,它通过调用EJB容器中的EJB组件来处理具体的业务逻辑。
使用JAX-RPC开发Web服务,可以按照以下的步骤进行:
1. 服务端点定义;
2. 服务描述;
3. 服务端点实现;
4. 服务端点部署;
5. 服务发布和发现。
下面使用JAX-RPC、Handler开发web service例子
运行环境:eclipse 插件wtp开发web service
1 最简单的Web服务
package com;
public interface Hello extends java.rmi.Remote {
public java.lang.String sayHello(java.lang.String string1) throws java.rmi.RemoteException;
}
接口实现文件
package com;
public class HelloBindingImpl implements com.Hello {
public java.lang.String sayHello(java.lang.String name) throws java.rmi.RemoteException {
return "A dynamic proxy hello to " + name + "!";
}
}
package com;
客户端handler
public class ClientHandler implements javax.xml.rpc.handler.Handler {
public ClientHandler() {
}
public boolean handleRequest(javax.xml.rpc.handler.MessageContext context) {
System.out.println("ClientHandler: In handleRequest");
return true;
}
public boolean handleResponse(javax.xml.rpc.handler.MessageContext context) {
System.out.println("ClientHandler: In handleResponse");
return true;
}
public boolean handleFault(javax.xml.rpc.handler.MessageContext context) {
System.out.println("ClientHandler: In handleFault");
return true;
}
public void init(javax.xml.rpc.handler.HandlerInfo config) {
}
public void destroy() {
}
public javax.xml.namespace.QName[] getHeaders() {
return null;
}
}
服务器端handler
package com;
public class ServerHandler implements javax.xml.rpc.handler.Handler {
public ServerHandler() {
}
public boolean handleRequest(javax.xml.rpc.handler.MessageContext context) {
System.out.println("ServerHandler: In handleRequest");
return true;
}
public boolean handleResponse(javax.xml.rpc.handler.MessageContext context) {
System.out.println("ServerHandler: In handleResponse");
return true;
}
public boolean handleFault(javax.xml.rpc.handler.MessageContext context) {
System.out.println("ServerHandler: In handleFault");
return true;
}
public void init(javax.xml.rpc.handler.HandlerInfo config) {
}
public void destroy() {
}
public javax.xml.namespace.QName[] getHeaders() {
return null;
}
}
2.服务描述和服务端点实现;
创建web service后自动生成HelloBindingImpl.wsdl文件和服务端点实现文件
3.服务端点部署
在server-config的service标签中添加
<requestFlow>
<handler type="java:org.apache.axis.handlers.JAXRPCHandler">
<parameter name="scope" value="session"/>
<parameter name="className" value="com.ClientHandler"/>
</handler>
<handler type="java:org.apache.axis.handlers.JAXRPCHandler">
<parameter name="scope" value="session"/>
<parameter name="className" value="com.ServerHandler"/>
</handler>
</requestFlow>
<responseFlow>
<handler type="java:org.apache.axis.handlers.JAXRPCHandler">
<parameter name="scope" value="session"/>
<parameter name="className" value="com.ServerHandler"/>
</handler>
<handler type="java:org.apache.axis.handlers.JAXRPCHandler">
<parameter name="scope" value="session"/>
<parameter name="className" value="com.ClientHandler"/>
</handler>
</responseFlow>
客户端调用方法
package com;
import javax.xml.namespace.QName;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceFactory;
import java.net.URL;
public class HelloClient {
public static void main(String[] args) throws Exception {
String UrlString = "http://localhost:8080/WSHandler/services/HelloBindingImpl?wsdl";
//http://localhost:8080/WSHandler/services/HelloBindingImpl
String nameSpaceUri = "http://com";
String serviceName = "HelloBindingImplService";
String portName = "HelloBindingImpl";
//调用的web服务的url地址,这里是一个http请求,希望得到的结果是wsdl文档。
URL helloWsdlUrl = new URL(UrlString);
ServiceFactory serviceFactory = ServiceFactory.newInstance();
Service helloService = serviceFactory.createService(helloWsdlUrl,new QName(nameSpaceUri, serviceName));
java.util.List list = helloService.getHandlerRegistry().getHandlerChain(new QName(nameSpaceUri, portName));
list.add(new javax.xml.rpc.handler.HandlerInfo(ClientHandler.class,null,null));
// 为对象获得动态代理
//传入getPort()方法的是一个接口定义,它将被用作在运行时创建动态代理的模版
Hello myProxy = (Hello) helloService.getPort(new QName("HelloBindingImplService", portName),com.Hello.class);
//使用java.lang.reflect.InvocationHandler.Invoke()调用服务
System.out.println(myProxy.sayHello("Buzz"));
}
}
回复Comments
{commenttime}{commentauthor}
{CommentUrl}
{commentcontent}