不同Web主机上的Servlet之间数据对象的相互传输
2008-03-28 14:51
465 查看
为什么要这样做
在目前所做的一个项目中,我们使用了两台独立的数据库服务器,出于安全方面的考虑,我们同时使用两台Web服务器分别操作这两个数据库。
由于数据库服务器A和服务库服务器B之间存在着数据的交换,而WEB服务器A并不能直接访问数据库服务器B,同理WEB服务器B也不能直接访问数据库服务器A。这样的交换只能是通过两台Web主机来进行。而在绝大多数时候,我们涉及的是较大规模的数据交换,使用带参数的格式显然不能满足我们的要求,这就涉及了不同Web主机上的Servlet之间数据对象的相互传输的问题。
使用通常的Application域或是Session域的javabean看上去不能满足我们的要求,虽然我们相信会有很多更为完美的方案可以解决这个问题,但是我们今天想看看如何直接通过HTTP连接来完成这样的传输。
首先对于我们的每一个独立的应用来说,两台WEB服务器都会存在一个主次的关系,情况也许是这样的:访问者访问WEB服务器A上的一个servlet A,而这个servlet A产生一个数据对象传输到WEB服务器B上的另一个servlet B,servlet B接收到这个数据对象后对其进行相应的处理,然后它可能还会生成另一个数据对象传输到servlet A中。这样的过程看上去有点象一个远程函数调用的概念。限于篇幅的限制,我们这里讨论一种较为简单的情况,test将passobject传输到test2,test2对passobject进行处理后将其传回到test。
简单示例的源码
首先,我们需要在两台WEB主机上分别建立对passobject的定义,在两台主机上的定义应该是完全一样,这样的类定义和我们通常使用并没有什么不同。只是这样的类必须实现序列化,也就是要实现Serializable:
在其中的一台web主机上建立。除去加注释的那几行,这完全是一个通常意义上的用于显示的servlet,不过那几行的内容看上去也许会有点让你眼花缭乱。这几行将数据对象传输到了另一台主机的test2中,并接收经过test2处理的数据对象。对于这里所涉及的一些不太常用的API,我们将会在最后一并说明。
在其中的另一台web主机上建立,用来接收test发送的数据对象,并对其进行处理后返回到test。
程序中涉及的部分API的说明
URL类表示了一个统一资源路径。这样的资源可能是一个文件或目录,也可能是更为复杂的诸如数据库的查询或是搜索引擎。
在我们的程序中使用了URL的一种构造函数:
直接使用字符串作为构造函数的参数,这实际上是URL的众多构造函数中最为简单的一种。
此外,我们还用到了URL的openConnection()方法:
该方法返回了一个URLConnection对象。每次调用该方法时会开启一个到指定URL的新的连接。
这里需要注意的是,调用该方法的结果是建立了一个连接,这与通常的页面跳转完全是两回事。在更多的情况下,这里仅仅是建立了一个连接的通路,而并没有实现任何其它的操作。
这是一个抽象类,是所有反映application和一个URL之前的通信的类的超类。这个类的实例可以用来对一个URL表示的资源进行读写。
在我们的程序中我们使用了这个类的如下方法:
这是一个抽象类,是所有反映一个二进制输出流的类的超类。一个这样的输出流可以对二进制数据进行输出或发送。
该类用来向一个OutputStream写入java的对象。这个对象可以使用ObjectInputStream进行读取或再造。
只有实现java.io.Serializable接口的对象可以写入该数据流中。
在我们的程序中还使用了该类的writeObject()方法:
将指定的对象写入ObjectOutputStream。
这是一个抽象类,是所有反映一个二进制输入流的类的超类。
一个ObjectInputStream对一个使用ObjectOutputStream写入的对象进行解析。
在我们的程序中使用了该类的readObject()方法:
从一个ObjectInputStream中读取一个对象。
程序执行的结果
如果一切正常,访问test.Test你应该可以看到这样的结果:
其中yzysynew,new是对象原来的内容,而yzysyold,new所反映的那个对象已经是传送到test2后经test2处理过的了。
在目前所做的一个项目中,我们使用了两台独立的数据库服务器,出于安全方面的考虑,我们同时使用两台Web服务器分别操作这两个数据库。
由于数据库服务器A和服务库服务器B之间存在着数据的交换,而WEB服务器A并不能直接访问数据库服务器B,同理WEB服务器B也不能直接访问数据库服务器A。这样的交换只能是通过两台Web主机来进行。而在绝大多数时候,我们涉及的是较大规模的数据交换,使用带参数的格式显然不能满足我们的要求,这就涉及了不同Web主机上的Servlet之间数据对象的相互传输的问题。
使用通常的Application域或是Session域的javabean看上去不能满足我们的要求,虽然我们相信会有很多更为完美的方案可以解决这个问题,但是我们今天想看看如何直接通过HTTP连接来完成这样的传输。
首先对于我们的每一个独立的应用来说,两台WEB服务器都会存在一个主次的关系,情况也许是这样的:访问者访问WEB服务器A上的一个servlet A,而这个servlet A产生一个数据对象传输到WEB服务器B上的另一个servlet B,servlet B接收到这个数据对象后对其进行相应的处理,然后它可能还会生成另一个数据对象传输到servlet A中。这样的过程看上去有点象一个远程函数调用的概念。限于篇幅的限制,我们这里讨论一种较为简单的情况,test将passobject传输到test2,test2对passobject进行处理后将其传回到test。
简单示例的源码
passobject.java |
package test; import java.io.*; public class PassObject implements Serializable { String PassValue1; String PassValue2; public void setNewPassObject() {PassValue1="yzysynew"; PassValue2="new"; } public void setOldPassObject() {PassValue1="yzysyold"; } } test.java |
package test; import java.sql.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import java.io.*; import java.net.*; public class Test extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {PassObject passobject = new PassObject(); passobject.setNewPassObject(); PrintWriter out = response.getWriter(); out.println(passobject.PassValue1); out.println(passobject.PassValue2); //创建一个新的URL实例url URL url = new URL("http://141.56.16.8/examples/servlet/test.Test2"); //根据url建立连接 URLConnection con = url.openConnection(); //设置该连接可写 con.setDoOutput(true); //禁用cache con.setUseCaches(false); //取出输出流 OutputStream outs=con.getOutputStream(); //将该输出流转换为对象输出流 ObjectOutputStream objout = new ObjectOutputStream(outs); //将要传输的对象写入该对象输出流中 objout.writeObject(passobject); //取得返回的输入流 InputStream in = con.getInputStream(); //将该输入流定义为对象输入流 ObjectInputStream objStream; objStream = new ObjectInputStream(in); //按指定类的格式读取输入流的内容 try { passobject=(PassObject)objStream.readObject(); out.println(passobject.PassValue1); out.println(passobject.PassValue2); } catch (java.lang.ClassNotFoundException ysy ) { out.println("fail"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { doGet(request, response); } } test2.java |
package test; import java.sql.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import java.io.*; import java.net.*; public class Test2 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {//封装用于返回的对象输出流 ObjectOutputStream out = new ObjectOutputStream(response.getOutputStream()); //封装用于接收的对象输入流 ObjectInputStream in = new ObjectInputStream(request.getInputStream()); PassObject passobject=new PassObject(); //按指定类的格式读取对象输入流中的内容 try { passobject=(PassObject)in.readObject(); } catch (java.lang.ClassNotFoundException ysy ) { } //对接受到的数据对象进行处理 passobject.setOldPassObject(); //将处理后的数据对象返回到对象输出流中 out.writeObject(passobject); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { doGet(request, response); } } |
java.net.URL |
在我们的程序中使用了URL的一种构造函数:
URL(String spec) |
此外,我们还用到了URL的openConnection()方法:
public URLConnection openConnection() throws IOException |
这里需要注意的是,调用该方法的结果是建立了一个连接,这与通常的页面跳转完全是两回事。在更多的情况下,这里仅仅是建立了一个连接的通路,而并没有实现任何其它的操作。
java.net.URLConnection |
在我们的程序中我们使用了这个类的如下方法:
getInputStream public InputStream getInputStream() throws IOException 返回从这个连接读取的一个输入流 getOutputStream public OutputStream getOutputStream() throws IOException 返回一个用于写入这个连接的输出流 setDoOutput public void setDoOutput(boolean dooutput) 设置该连接是否可以写入 setUseCaches public void setUseCaches(boolean usecaches) 设置该连接是否使用cache java.io.OutputStream |
java.io.ObjectOutputStream |
只有实现java.io.Serializable接口的对象可以写入该数据流中。
在我们的程序中还使用了该类的writeObject()方法:
public final void writeObject(Object obj) throws IOException |
java.io.InputStream |
java.io.ObjectInputStream |
在我们的程序中使用了该类的readObject()方法:
public final Object readObject() throws OptionalDataException, ClassNotFoundException, IOException |
程序执行的结果
如果一切正常,访问test.Test你应该可以看到这样的结果:
yzysynew new yzysyold new |
相关文章推荐
- 不同Web主机上的Servlet之间数据对象的相互传输
- 不同Web主机上的Servlet之间数据对象的相互传输
- scp 在不同主机之间数据传输
- scp 在不同主机之间数据传输
- scp 在不同主机之间数据传输
- scp 在不同主机之间数据传输
- java不同对象之间的数据交互(通用)
- linux主机之间数据传输
- Android中级教程之(五)----->不同Activity之间的数据传递,Bundle对象的使用!
- web不同域之间互传数据
- web服务器与file服务器不同域(Domain)之间的数据交换
- 【Android中级教程(三)之不同Activity之间的数据传递---Bundle对象的使用】的改进!
- Ex3.10 不同Activity之间的数据传递——Bundle对象的实现
- 不同Activity之间的数据传递--Bundle对象的实现
- Android消息机制之实现两个不同线程之间相互传递数据相互调用
- gson的简要使用--关于web端和android之间的数据传输
- linux下不同主机之间的文件传输
- 【WP开发】不同客户端之间传输加密数据
- Android中级教程(三)之不同Activity之间的数据传递---Bundle对象的使用!
- Android笔记三.不同Activity之间的传递数据(Bundle对象的使用)