如何在Servlet里远程调用 Web Service

如题所述

在J2EE世界中要实现远程方法调用的手段很多,如Spring:Hessian/Burlap, RMI, and JAX-RPC,
JMS
,webservice。等等,你可能有过编写EJB的经验或对RMI有所了解,如果你使用过Spring框架的远程调用,你可能你各种远程调用方法就比较清楚和了解,可是你未必尝试过一切都是自己构造来实现远程调用,这里我们尝试同过编写一个简单的Servlet(极其简单)通过http实现远程方法调用。希望对于servlet你有一个新的认识,在下一篇文章中,我会尝试给你另一个servlet的新的应用。[@more@]让我们先从这个servlet开始:
public class RemoteServlet extends HttpServlet {
public
void service(HttpServletRequest req,
HttpServletResponse resp) throws ServletException
,java.io.IOException{
System.out.print("BaseDataServlet
service received a remote request");
ObjectInputStream in = new
ObjectInputStream(req.getInputStream());
resp.setContentType("application/octest-stream");
ByteArrayOutputStream
byteout = new
ByteArrayOutputStream();
ObjectOutputStream out = new
ObjectOutputStream(byteout);
Request request;
try {
request = (Request)in.readObject();//读取远程调用请求的封装对象
//System.out.println(":n"+request.toString());
RequestProcessor processor=new
RequestProcessor();//请求解析对象
out.writeObject(processor.processorLocalhost(request));//执行请求并回写结果 out.flush();
} catch (ClassNotFoundException e) {

e.printStackTrace();
}
byte buf[]=
byteout.toByteArray();
resp.setContentLength(buf.length);
ServletOutputStream
servletout =
resp.getOutputStream();
servletout.write(buf);
servletout.close();

}
}

这个servle从输入流读取远程调用的请求(Request对象):request =
(Request)in.readObject();再由解析器RequestProcessor调用请求的对象,然后将结果回传给请求客户端。Request封装了请求的信息:

/**
* 对远程调用请求的封装
* @author wuxinyang
*/
public class Request implements
java.io.Serializable{
//目标地址,如果为localhost则为本地方法调用。
private String server;
//spring
bean的配置名称,如果配置了该值则通过spring配置装载service。 private String serviceBeanName;
//服务的接口class名称,必须带包名 private String serviceInterface; //要调用的方法名称
private String methodName;
//返回类型,该值不是必须的。 private String returnType="void";
//传入的参数列表 private java.util.List arguments=new java.util.ArrayList();
/**
* 构造方法
*
@param server 目标地址
* @param serviceInterface spring bean的配置名称
* @param
methodName 方法名称
*/
public Request(String server, String serviceInterface,
String methodName) {
super();
this.server =
server;
this.serviceInterface = serviceInterface;
this.methodName =
methodName;
}
/**
* 添加调用参数
* @param arg 调用参数
*/
public void
addArgument(Object arg){
arguments.add(arg);
}
public java.util.List
getArguments() {
return arguments;
}
public void
setArguments(java.util.List arguments) {
this.arguments =
arguments;
}
public String getMethodName() {
return
methodName;
}
public void setMethodName(String methodName)
{
this.methodName = methodName;
}
public String getReturnType()
{
return returnType;
}
public void setReturnType(String returnType)
{
this.returnType = returnType;
}
public String getServer() {
return
server;
}
public void setServer(String server) {
this.server =
server;
}
public String getServiceInterface() {
return
serviceInterface;
}
public void setServiceInterface(String
serviceInterface) {
this.serviceInterface = serviceInterface;
}
public
String getServiceBeanName() {
return serviceBeanName;
}
public void
setServiceBeanName(String serviceBeanName) {
this.serviceBeanName =
serviceBeanName;
}
/**
* @see
java.lang.Object#toString()
*/
public String
toString() {
return new
ToStringBuilder(this).append("serviceInterface",
this.serviceInterface).append("serviceBeanName",
this.serviceBeanName).append("returnType",
this.returnType)
.append("arguments",
this.arguments).append("server",
this.server).append("methodName",
this.methodName)
.toString();
}
}
RequestProcessor类有如下方法:

public Object processorLocalhost(Request request) {
String
serviceInterface = request.getServiceInterface();//服务的接口class名称(被调用者的接口)
try
{
Object
service;
if(request.getServiceBeanName()!=null){
//通过Spring初始化
service=com.westerasoft.common.SpringBeanFactory.getBean(request.getServiceBeanName());
}
else{
//初始化
service
= Class.forName(serviceInterface).newInstance();
}
Method method =
null;
BeanInfo beanInfo =
Introspector.getBeanInfo(service.getClass());
MethodDescriptor[]
methodDescriptors = beanInfo.getMethodDescriptors();
for (int i = 0; i <
methodDescriptors.length; i++) {
MethodDescriptor descriptor =
methodDescriptors[i];
method = descriptor.getMethod();
if
(method.getName().equalsIgnoreCase(request.getMethodName()))
break;
method
= null;
}
if (method != null) {
//调用请求的方法
return
method.invoke(service, request.getArguments().toArray());
}
} catch
(Exception e) {
e.printStackTrace();
}
return null;
}

客户端类如下:

public class RequestProcessorTest {
public static void main(String[] args)
{
String urlString = "http://localhost:8080/wcommons/servlet/BaseDataServlet";
//urlString="localhost";
//请求调用远程接口com.westerasoft.common.dnet.RemoteService的方法gbToUtf8(String
src)
Request request = new
Request(urlString,
"com.westerasoft.common.dnet.RemoteService",
"gbToUtf81");
request.addArgument("中国人民解放军ABC");//添加调用参数即方法gbToUtf81的参数

Object answer = (Object) processor(request
);
System.out.println(answer);
request = new
Request(urlString,null,"findUsers");
//请求调用远程接口userManager(Spring配置的bean
name)的findUsers()方法
request.setServiceBeanName("userManager"); answer =
(Object) processor(request );
System.out.println(answer);
}

private Object processor(Request request) {
try {
URL url = new
URL(request.getServer());
java.net.URLConnection con =
url.openConnection();
con.setUseCaches(true);
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestProperty("Content-type",
"application/octest-stream");
con.setRequestProperty("Content-length", "" +
-1);
ObjectOutputStream dataout = new
ObjectOutputStream(con
.getOutputStream());
dataout.writeObject(request);
dataout.flush();
dataout.close();
ObjectInputStream
in = new ObjectInputStream(con.getInputStream());
Object obj =
in.readObject();
in.close();
return obj;
} catch (Exception e)
{
e.printStackTrace();
}
return null;
}
}

是不是极其简单(^_^),可以实现远程接口调用。记住你是通过servlet服务提供的,所以你也可以很容易的控制只对经过授权的用户能够远程调用。实际应用中你也许需要更完善和强大的远程调用框架,比如支持hibernate的延迟加载特性,和异构系统等等,那么有很多好的解决方案供你选择,已知的EJB,Spring,Webservice等等,都是你可以考虑的好东东。
转载,仅供参考,祝你愉快,满意请采纳。
温馨提示:答案为网友推荐,仅供参考

相关了解……

你可能感兴趣的内容

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网