Servlet与Applet

Servlet传送查询记录集给Applet  
这个问题在csdn上已经有讨论了http://www.csdn.net/expert/topic/971/971710.xml. 
具体的需求就不讲了,这里把我的实现步骤详细写下,与<<Servlet传送对象给Applet使用>>中提到的方法 
一样.用到的CachedRowSet可以到 
http://java.sun.com//Download4?userid=zlyperson&platform=zip&button=continue&config-file=rowset-1_0-ea4.config 
去下.还有一个netscape的包,在C:\WINNT\java\Packages\0S0W0NFX.ZIP中. 
我也把所需要的包及我的实现代码打成了包,其中包扩了CachedRowSet&netscape&本文. 
http://63.210.240.215/rookieport/rowset.jar 
下面给出全部代码和配置,其中Applet部分涵盖 
了Javascript与Applet的互相调用,对于该部分不感兴趣的朋友可以复略. 

第一步,实现Servlet 

package exapplet; 
import java.io.*; 
import java.sql.*; 
import javax.sql.*; 
import sun.jdbc.rowset.*; 
import javax.servlet.*; 
import javax.servlet.http.*; 

public class MyServlet extends HttpServlet 
{ 
static { 
try { 
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 
} catch (Exception e) { 
e.printStackTrace(); 
} 
} 

public void doGet(HttpServletRequest req,HttpServletResponse res) 
throws ServletException,IOException 
{ 
try { 
Connection dbconn = DriverManager.getConnection("jdbc:odbc:BlueSite"); 
Statement stmt = dbconn.createStatement(); 
String dbsql = req.getParameter("DBSQL"); 
ResultSet dbrest = stmt.executeQuery(dbsql); 
CachedRowSet crs = new CachedRowSet(); 
crs.populate(dbrest); 
dbrest.close(); 
stmt.close(); 
dbconn.close(); 
//传回对象给Applet 
res.setContentType("application/octet-stream"); 
ObjectOutputStream oos = new ObjectOutputStream(res.getOutputStream()); 
oos.writeObject(crs); 
oos.close(); 
} catch (Exception exp) { 
exp.printStackTrace(); 
} 
} 
public String getServletInfo() 
{ 
return "A simple Servlet!"; 
} 
} 

第二步,实现提取对象的Applet 
package exapplet; 
import java.awt.*; 
import java.applet.*; 
import java.io.*; 
import java.net.*; 
import javax.sql.*; 
import sun.jdbc.rowset.*; 
import netscape.javascript.*; 

public class MyAppletB extends java.applet.Applet 
{ 
public void init() 
{ 
} 
public void paint(Graphics g) 
{} 

//This method will be call in html 
public void invoke() { 
try { 
URL url = new URL("http://Liaoyuan:8080/WorkingRoom/exapplet/PostToApplet?DBSQL=Select%20TopicName,TopicName,TopicName%20from%20Topic"); 
//注意url中的空个用%20替代. 

URLConnection urlcon = url.openConnection(); 
urlcon.connect(); 
ObjectInputStream ois=new ObjectInputStream(urlcon.getInputStream()); 
CachedRowSet crs = (CachedRowSet)ois.readObject(); 
ois.close(); 
while ( crs.next() ) { 
JSObject.getWindow(this).call("alert",new String[]{crs.getString(1)}); 
} 
crs.close(); 
} catch (Exception e) { 
} 
} 
} 

第三步,配制WebServer(我用的是Tomcat4.0) 
拷贝编译后的MyServlet.class到相应目录下,或者下载我打的包到WEB-INF\lib下 
编辑对应的web.xml文件,确保下面的内容正确 
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> 
<web-app> 
<servlet> 
<servlet-name>PostToApplet</servlet-name> 
<servlet-class>exapplet.MyServlet</servlet-class> 
</servlet> 

<servlet-mapping> 
<servlet-name> 
PostToApplet 
</servlet-name> 
<url-pattern> 
/exapplet/PostToApplet 
</url-pattern> 
</servlet-mapping> 
</web-app> 



第四步,编写html文件 
提取对象的html 
<HTML> 
<HEAD> 
<TITLE> New Document For Using Applet </TITLE> 
</HEAD> 

<BODY> 
Hello This is a Test!<br> 
<APPLET id="obj_applet" align=center code="exapplet.MyAppletB" codeBase="." width=400 height=300 name="obj_applet" archive="BV7RFD3P.ZIP"></APPLET> 
<Input type=button value="CallAppletMethod" οnclick="callApplet()"> 
<Script language=javascript> 
function callApplet() 
{ 
obj_applet.invoke(); 
} 
</Script> 
</BODY> 
</HTML> 

转载地址:http://iask.sina.com.cn/b/998364.html 


以下是第二篇:Applet与Servlet通讯的四种方法及其比较

Applet与Servlet之间的联系一般是间接的,即页面请求由浏览器发送给Servlet,作为回答,Servlet将结果生成HTML文档发送给浏览器。很多时候在Servlet与Applet之间建立直接的联系是没有必要的,但如果要显示一些实时的动态数据,如聊天室窗口、新闻显示、股市行情等,建立两者之间的直接联系就很有用了。特别地,在较为复杂的分布式Java应用中,这种通讯更是必不可少。在客户端Java程序与服务器端Java程序之间建立这种复杂的交互方式仅仅使用Servlet与Applet API是不够的,本文为你介绍和比较四种通讯方式:通过HTML页面传递参数,用java.net包的网络功能建立直接网络连接,远程方法调用(RMI)与CORBA。 
   一、通过HTML页面传递Applet参数 

   通过HTML页面传递参数是在Servlet与Applet之间建立联系最为常用的方法。Servlet只要把传递给Applet的参数写入HTML页面就可以了。这种通讯是单向的,用于实现Servlet对Applet的控制。其实现方法类如: 

// doGet()方法生成一个包含Applet的HTML页面, 
// 该Applet需要一个Data参数 

public void doGet(HttpServletRequest request,HttpServletResponse response) 
throws ServletException, IOException { 
response.setContentType("text/html"); 
PrintWriter out = new PrintWriter ( response.getOutputStream()); 
out.write("< HTML>< HEAD>< TITLE> HTML Example< /TITLE> < /HEAD>< BODY>"); 
out.write("Servlet通过PARAM标记传递参数给Applet. "); 
out.write("< APPLET code=\"SimpleApplet\" width=\"225\" height=\"149\">"); 
// 写入PARAM标记 
out.write("< param name=\"Data\" value=\""); 
out.write(java.text.DateFormat.getDateInstance().format(new java.util.Date())); 
out.write("\">< /APPLET>< /BODY>< /HTML>"); 
out.close(); 
} 


   这种方法很简单,但它有两个缺点。首先,所有参数都是静态的,即一旦HTML页面发送完成,要更新其中部分数据就很困难了。虽然可以使用HTTP的刷新机制,但这种刷新需要重新下载整个页面,效率是很低的。第二,如果需要传递给Applet的数据量很大或数据结构很复杂,就会使得HTML页面过于庞大或复杂了。 
二、用java.net包建立双向通讯
   第二种方法是利用java.net包提供的网络能力。以有连接流通讯方式为例,在服务
  器端的操作为一般为:
   ⑴ 创建一个ServerSocket对象,在指定端口监听客户端发来的请求。
   ⑵ 在接收到请求时accept()方法将返回一个Socket对象。
   ⑶ 用上述Socket对象创建输入、输出流对象。
   ⑷ 通过输入、输出流与客户交互。
   ⑸ 交互完毕,关闭输入、输出流与Socket。
   ⑹ 服务程序运行结束,关闭ServerSocket。
   实现代码代码类如:
try{
  boolean flag=true;
  Socket clientSocket=null;
  ServerSocket serverSocket = new ServerSocket(0);
  System.out.println("Server listen on: " +serverSocket.getLocalPort());
  while(flag){
  clientSocket=serverSocket.accept();
  DataInputStream is=new DataInputStream( new bufferedInputStream(clientSocket
  .getInputStream()));
  PrintStream os=new PrintStream( new bufferedOutputStream(clientSocket.getOut
  putStream()));
  // 处理Applet请求
  os.close();
  is.close();
  clientSocket.close();
  }
  serverSocket.close();
  }catch( IOException e){
  System.err.println(" Exception: "+e);
  }

   在客户端的操作为:
   ⑴ 创建Socket对象建立与服务器的连接。
   ⑵ 用该Socket对象创建输入、输出流。
   ⑶ 与服务器交互。
   ⑷ 交互完毕,关闭输入、输出流与Socket。
   实现代码类如:
try {
  Socket clientSocket =new Socket("serverName",7);
  OutputStream os=clientSocket.getOutputStream();
  DataInputStream is=new DataInputStream( clientSocket.getInputStream());
  // 其它操作.
  os.close();
  is.close();
  clientSocket.close();
  }catch(Exception e){
  System.err.println("Exception:"+e);
  }

   这种方法只依赖于标准的Java网络支持,不需要用到附加的软件包或工具, 因此
  显得相当简洁和灵活,易于实现某些特殊的需要。但在另一方面,服务器端对进入请求
  以及客户端对返回结果的分析工作量较大。如果服务器端要执行大量的操作,可以考虑
  使用RMI。
   三、远程方法调用RMI
   Java的RMI技术显著地改善了客户程序操作复杂的服务器端对象的能力。对Applet
  来说,服务器端对象所提供的远程方法可以象普通的客户端句柄一样调用。使用RMI时应
  先定义远程接口,即一个继承自java.rmi.Remote的公用接口。在该接口中定义要求在服
  务器上运行的方法,所有这些方法的throws子句至少应该声明java.rmi.RemoteExcepti
  on异常。
   接下来是实现远程接口,远程接口的实现类应该:
   ⑴ 指定所实现的一个或多个接口。
   ⑵ 定义远程对象的构造方法。
   ⑶ 提供所有可供远程调用的方法的实现。
   ⑷ 创建和安装安全管理器。
   ⑸ 创建一个或多个远程对象实例。
   ⑹ 注册至少一个远程对象。
   下面的代码实现一个返回日期字符串的getData()远程方法,该方法由接口RMISer
  v2App定义:
// 本类继承自UnicastRemoteObject,实现接口serv2app
  package com.servletsolutions.serv2app.rmi;
  import java.rmi.*;
  import java.rmi.server.*;
  public class RMIImplementation extends UnicastRemoteObject
  implements RMIServ2App{
  public RMIImplementation() throws RemoteException{}
  public String getData() throws RemoteException{
  return java.text.DateFormat.getDateInstance().format(
  new java.util.Date());
  }
  public static void main(String[] args){
  // 安全管理器
  System.setSecurityManager(new RMISecurityManager());
  try{
  // 远程对象实例
  RMIImplementation bootStrap = new RMIImplementation();
  // 注册
  Naming.bind(args[0], bootStrap);
  System.out.println(args[0] + " 注册成功");
  }catch(Exception e){
  System.err.println("注册失败.");
  System.err.println(e);
  }
  }
  }

   在客户端,Applet对接口RMIServ2App的引用通过调用Naming.lookup(String)获得
  ,如下所示:
   RMIServ2App obj = (RMIServ2App)Naming.lookup("//" + getCodeBase().getHo
  st() + "/ServerName");
   除了编译Java代码之外,还要用rmic编译器生成远程对象的存根和骨架。存根(S
  tub)是远程对象在客户端的代理,它将RMI调用传递给服务器端的骨架(Skeleton),
  后者负责将该调用传递给实际的远程方法。例如执行命令rmic com.servletsolutions.
  RMIImplementation,则生成的两个类文件分别为RMIImplementation_Stub.class 和RM
  IImplementation_Stub.class,前者封装入Applet且运行于客户端,后者封装入Servle
  t且运行与服务器端。
   当大量的数据是由服务器端的对象动态提供时使用RMI是非常合适的。虽然RMI支持
  面向对象的分布式编程,但它要求客户端和服务器端都是Java程序。因此,对于使用混
  合语言开发的应用来说,CORBA比RMI更为适用。
   四、使用CORBA
   CORBA即公用对象请求代理体系(Common Object Request Broker Architecture)
  ,它的使用方法类似于RMI:定义接口,使用某个工具创建Stub和Skeleton,实现接口,
  在服务器上注册后客户就可以像本地对象一样访问远程对象了。两者主要的不同之处在
  于,CORBA使用一种语言中立的接口定义语言(IDL)来定义接口,IDL是一种可用于混合
  语言环境的更为广泛的协议集。CORBA最大的缺点在于客户本身必须具备调用ORB的能力
  ,这往往意味着增加一个体积较大的JAR文件。
   下面的CORBAServ2App.idl是上述getData()接口的IDL描述,它定义了一组与Java
  包名字对应的嵌套模块:
module com {
  module servletsolutions {
  module serv2app {
  module corba {
  interface CORBAServ2App{
  string getData();
  };
  };
  };
  };
  };

   可以用idl2java从IDL文件生成对应的java文件。其中_CORBAServ2AppImplBase.j
  ava包含了描述该接口的java抽象类,下面的CORBAImplementation类继承自抽象类_COR
  BAServ2AppImplBase并具体实现getData()方法:
package com.servletsolutions.serv2app.corba;
  public class CORBAImplementation extends _CORBAServ2AppImplBase {
  CORBAImplementation(String s){ super(s); }
  public String getData(){
  return java.text.DateFormat.getDateInstance().format(new java.util.Date());
  }
  }

   为了让该类可以被客户访问,Servlet中还应该创建其实例。代码如下所示:
  // 在Servlet的init()方法中初始化CORBAImplementation对象
  // 其中BOA(Basic Object Adapter)的作用类似于RMI中的注册服务

转自 :http://hi.baidu.com/sharebophar/item/e05fede04d2122b72e140b09

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值