500分,求一Applet与servlet通讯的例子..... 在applet里用urlconnection与servlet通信。即是applet发个http请求给servlet,然后接收从servlet输出的内容。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 applet与servlet通讯showStatus(testField1.getText());URL servlet=new URL(this.getCocumentBase(),"servlet/GetParameterServlet");URLConnection connection=servlet.openConnection();Connection serUseCaches(false);connection.setDoOutut(true);ByteArrayOutputStream byteStream=new ByteArrayOutputStream(1024);PrintWrite out=new PrintWrite(byteStream,true);String postData="Name="+URLEncoder.encode(textField1.getText());out.print(postData);out.flush();String lengthString=String.valueOf(byteStream.size());connection.setRequestProperty("Content-Length",lengthString);connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");byteStream.writeTo(connection.getOutputStream());BufferedReader br=new BufferReader(new InputStreamReader(connection.getInputStream()));textArea1.setText("");String s;for(;(s=br.readLine())!=null&&s.length()>0;textArea1.appendText(s+"\n"));servlet source//GetPrameterServletimport java.io.*;import javax.servlet.*;import javax.servlet.http.*;import java.util.*;public class GetParameterServlet extends HttpServlet{ public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{ response.setContentType("text/html"); PrintWrite out=response.getWriter(); String title="Reading Request Parameters"; String name=request.getParameter("Name"); out.println(title); out.println("Hello:"+name); } } 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.getOutputStream())); // 处理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.RemoteException异常。 接下来是实现远程接口,远程接口的实现类应该: ⑴ 指定所实现的一个或多个接口。 ⑵ 定义远程对象的构造方法。 ⑶ 提供所有可供远程调用的方法的实现。 ⑷ 创建和安装安全管理器。 ⑸ 创建一个或多个远程对象实例。 ⑹ 注册至少一个远程对象。 下面的代码实现一个返回日期字符串的getData()远程方法,该方法由接口RMIServ2App定义: // 本类继承自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().getHost() + "/ServerName"); 除了编译Java代码之外,还要用rmic编译器生成远程对象的存根和骨架。存根(Stub)是远程对象在客户端的代理,它将RMI调用传递给服务器端的骨架(Skeleton),后者负责将该调用传递给实际的远程方法。例如执行命令rmic com.servletsolutions.RMIImplementation,则生成的两个类文件分别为RMIImplementation_Stub.class 和RMIImplementation_Stub.class,前者封装入Applet且运行于客户端,后者封装入Servlet且运行与服务器端。 当大量的数据是由服务器端的对象动态提供时使用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.java包含了描述该接口的java抽象类,下面的CORBAImplementation类继承自抽象类_CORBAServ2AppImplBase并具体实现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中的注册服务 public class CORBAServ servlet与applet的交互2000-09-16· 清风·yesky-------------------------------------------------------------------------------- Applet与Java Servlet可以通过HTTP协议的GET和POST进行交互,Applet必须打开一个到指定的servlet URL的连接。一旦建立了此连接,applet就可以从servlet得到一个output stream或者一个input stream。applet可以通过发送一个GET或者一个POST方法将数据发送到servlet。一 GET方法 使用GET方法发送数据到servlet,applet必须将name/value 配对参数翻译成为实际的URL字符串。例如要发送name/value配对信息"LastName=Jones",servlet URL如下:http://www.foo.com/servlet/TestServlet?LastName=Jones如果还有另外的配对信息,则用一个’&’符号将它们连接。方法如下:http://www.foo.com/servlet/TestServlet?LastName=Jones&FirstName=Joe 在应用中,必须翻译每一个按name/value配对的信息。为发送一个方法GET方法到servlet,applet用类java.net.URLConnection来实现。下面的代码片段将实现:String location = "http://www.foo.com/servlet/TestServlet?LastName=Jones";URL testServlet = new URL(location);URLConnection servletConnection = testServlet.openConnection();inputStreamFromServlet = servletConnection.getInputStream();// 从servlet读input。 一旦applet建立了一个到URL的连接,这时访问了来自servlet 的input stream。applet可以读这个input stream从而处理此数据。依赖servlet返回此数据的类型和格式。如果servlet 正返回定制的信息,需要创建一个定制的消息传输协议来实现applet 和 servlet通信(交互)。二、POST方法 使用POST方法发送数据到servlet,必须通知URL连接output stream发送数据。方法POST是很强大的,因为它可以发送任何形式的数据(诸如纯文本,二进制码之类)。您需要做的只是在HTTP 请求header中设置满意的类型。但是,此servlet必须可以处理由applet发送的此类型的数据。下面的代码片段显示了如何发送方法POST到一个servlet URL。// 连接servletString location = "http://www.foo.com/servlet/TestServlet";URL testServlet = new URL( servletLocation );URLConnection servletConnection = testServlet.openConnection(); // 通知此连接我们将要发送output并且要接收inputservletConnection.setDoInput(true); servletConnection.setDoOutput(true);//不能使用URL connection的缓存。servletConnection.setUseCaches (false);servletConnection.setDefaultUseCaches (false);// 指定我们将要发送的数据内容的类型为binary数据servletConnection.setRequestProperty("Content-Type", "<insert favorite mime type>");// 从servlet上取得input和output streams. . .// 将您的数据发送到servlet. . . applet用http隧道技术和servlet通讯import java.io.*;import java.applet.applet;import java.awt.*;public class TestDataStreamApplet extends applet{ String response; public void init(){ java.net.URL url=new java.net.URL(getDocumentBase(),"servlet/DataStreamEcho"); java.net.URLConnection con=url.openConnection(); con.serUseCaches(true); con.setDoOutput(true); con.setDoInput(true); ByteArrayOutputStream byteout=new ByteArrayOutputStream(); DataOutputStream out=new DataOutputStream(byteout); out.writeUTF("Hello world!"); out.flush(); byte buf[]=byteout.toByteArray(); con.setRequestProperty("Content-type","application/octest-stream"); con.setRequestProperty("Content-length",""+buf.length); DataOutputStream dataout=new DataOutputStream(con.getOutputStream()); dataout.write(buf); dataout.flush(); data.close(0; DataInputStream in=new DataInputStream(con.getInputStream()); response=in.readUTF(); System.out.println("read from server:"+response); in.close(); }catch(Exception e){ e.printStackTrace(); } } public void paint(Graphics g){ g.drawString("read from server:"+response,10,20); }}servlet sourceimport javax.servlet.*;import javax.servlet.http.*;import java.io.*;public class DataStreamEcho extends HttpServlet{ public void service(HttpServletRequest req.HttpServletResponse resp) throws ServletException,java.io.IoException{ DataInputStream in=new DataInputStream(req.getInputStream()); resp.setContentType("application/octest-stream"); ByteArrayOutputStream byteout=new ByteArrayOutputStream(); DataOutputStream out=new DataOutputStream(byteout); String response=in.readUTF(); out.writeUTF(response); out.flush(); byte buf[]=byteout.toByteArray(); resp.setContentLength(buf.length); ServletOutputStream servletout=resp.getOutputStream(); setvletout.write(buf); servletout.close(); }} 绝对给分!我选送出了350分请各位朋友查收,谁能帮小弟渡过此难关,我愿给他一个人1000分!swain(球球)暂时给你200分,你最后给我的例子,Applet编译通过,servlet却要改一个大小写的问题才通过,修改配置文件,浏览结果发现Applet启动,但Applet显示区域全是灰色的....... swain(球球)你上面说的第二种方法(用java.net包建立双向通讯)能不能给我一个完整的例子? servlet: public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(CONTENT_TYPE); try{ ObjectInputStream in=new ObjectInputStream(request.getInputStream()); String query_str=in.readObject().toString(); DataSource ds=new DataSource(); ds.readConfigData(); ds.open(); Query query=new Query(); query.setDataSource(ds); query.executeQuery(query_str); response.setContentType("application/octest-stream"); ObjectOutputStream out=new ObjectOutputStream(response.getOutputStream()); out.writeObject(query.columnNames); out.writeObject(query.table); String path=this.getServletConfig().getServletContext().getRealPath("/images/exc.gif"); System.out.println(path); ImageIcon img=new ImageIcon(path); out.writeObject(img); out.flush(); out.close(); query.close(); }catch(Exception e){ System.out.println("error:"+e.getMessage()); } }applet: try{ URL url=new URL(getDocumentBase(),"/servlet/qqpack.qqServlet"); URLConnection con=url.openConnection(); con.setUseCaches(true); con.setDoOutput(true); con.setDoInput(true); con.setRequestProperty("Content-type","application/octest-stream"); ObjectOutputStream out=new ObjectOutputStream(con.getOutputStream()); out.writeObject("select * from staticdb..deviceinfo"); out.flush(); out.close(); ObjectInputStream in=new ObjectInputStream(con.getInputStream()); Vector col=(Vector)in.readObject(); Vector data=(Vector)in.readObject(); ImageIcon img=(ImageIcon)in.readObject(); in.close(); //888888888888888888 for(int i=0;i<data.size();i++){ String name=((Vector)data.elementAt(i)).elementAt(1).toString().trim().toUpperCase(); ObjectButton jButton=new ObjectButton(img.getImage(),name); jPanel1.add(jButton); } jPanel1.add(new LineButton("aaaaaaaa")); jPanel1.updateUI(); }catch(Exception ee){ System.out.println("error:"+ee.getMessage()); } to swain(球球)好精彩! 我都想给你分呀! swain(球球)用servlet自动三秒钟读一个文本文件如何做呢? :能不能用servlet 在实现线程Runnable 接口的情况下,不停的返回数据,??作 者:FJY168所 球球好厉害呀,这篇帖子应该算是java版比较经典的了,怎么不加到精华区??? swain(球球)这问题解决了,我会给你加到1000分表示感谢! 这篇帖子应该算是java版比较经典的了!!!但是我还是没有调通!swain(球球)在吗? swain(球球) 我不能上QQ,请给我你的MAIL[email protected] Struts2如何提交请求 很简单的一个自制分页jar. javabean 中捕捉到了错误,如何解决? 安装了J2SDK1.4.2之后 流传递乱码问题 jsp ms-sql2005乱码问题 jquery easyui中的treegrid不显示数据,这样写对不对 本人24岁,还有软件开发的潜力吗,还适合做程序员吗 请教:下面的要求如何实现 求解这代码是什么意思 ?请推荐一些jsp的经典技术书籍??(?????( to skyyoung(路人甲).图像中参数传递问题。急!!!
URL servlet=new URL(this.getCocumentBase(),"servlet/GetParameterServlet");
URLConnection connection=servlet.openConnection();
Connection serUseCaches(false);
connection.setDoOutut(true);
ByteArrayOutputStream byteStream=new ByteArrayOutputStream(1024);
PrintWrite out=new PrintWrite(byteStream,true);
String postData="Name="+URLEncoder.encode(textField1.getText());
out.print(postData);
out.flush();
String lengthString=String.valueOf(byteStream.size());
connection.setRequestProperty("Content-Length",lengthString);
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
byteStream.writeTo(connection.getOutputStream());
BufferedReader br=new BufferReader(new InputStreamReader(connection.getInputStream()));
textArea1.setText("");
String s;
for(;(s=br.readLine())!=null&&s.length()>0;textArea1.appendText(s+"\n"));
servlet source//GetPrameterServletimport java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;public class GetParameterServlet extends HttpServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException{
response.setContentType("text/html");
PrintWrite out=response.getWriter();
String title="Reading Request Parameters";
String name=request.getParameter("Name");
out.println(title);
out.println("Hello:"+name);
}
}
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.getOutputStream()));
// 处理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.RemoteException异常。
接下来是实现远程接口,远程接口的实现类应该:
⑴ 指定所实现的一个或多个接口。
⑵ 定义远程对象的构造方法。
⑶ 提供所有可供远程调用的方法的实现。
⑷ 创建和安装安全管理器。
⑸ 创建一个或多个远程对象实例。
⑹ 注册至少一个远程对象。
下面的代码实现一个返回日期字符串的getData()远程方法,该方法由接口RMIServ2App定义:
// 本类继承自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().getHost() + "/ServerName");
除了编译Java代码之外,还要用rmic编译器生成远程对象的存根和骨架。存根(Stub)是远程对象在客户端的代理,它将RMI调用传递给服务器端的骨架(Skeleton),后者负责将该调用传递给实际的远程方法。例如执行命令rmic com.servletsolutions.RMIImplementation,则生成的两个类文件分别为RMIImplementation_Stub.class 和RMIImplementation_Stub.class,前者封装入Applet且运行于客户端,后者封装入Servlet且运行与服务器端。
当大量的数据是由服务器端的对象动态提供时使用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.java包含了描述该接口的java抽象类,下面的CORBAImplementation类继承自抽象类_CORBAServ2AppImplBase并具体实现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中的注册服务
public class CORBAServ
2000-09-16· 清风·yesky-------------------------------------------------------------------------------- Applet与Java Servlet可以通过HTTP协议的GET和POST进行交互,Applet必须打开一个到指定的servlet URL的连接。一旦建立了此连接,applet就可以从servlet得到一个output stream或者一个input stream。
applet可以通过发送一个GET或者一个POST方法将数据发送到servlet。
一 GET方法
使用GET方法发送数据到servlet,applet必须将name/value 配对参数翻译成为实际的URL字符串。例如要发送name/value配对信息"LastName=Jones",servlet URL如下:
http://www.foo.com/servlet/TestServlet?LastName=Jones
如果还有另外的配对信息,则用一个’&’符号将它们连接。方法如下:
http://www.foo.com/servlet/TestServlet?LastName=Jones&FirstName=Joe
在应用中,必须翻译每一个按name/value配对的信息。为发送一个方法GET方法到servlet,applet用类java.net.URLConnection来实现。下面的代码片段将实现:String location = "http://www.foo.com/servlet/TestServlet?LastName=Jones";
URL testServlet = new URL(location);
URLConnection servletConnection = testServlet.openConnection();
inputStreamFromServlet = servletConnection.getInputStream();
// 从servlet读input。
一旦applet建立了一个到URL的连接,这时访问了来自servlet 的input stream。applet可以读这个input stream从而处理此数据。依赖servlet返回此数据的类型和格式。如果servlet 正返回定制的信息,需要创建一个定制的消息传输协议来实现applet 和 servlet通信(交互)。
二、POST方法
使用POST方法发送数据到servlet,必须通知URL连接output stream发送数据。方法POST是很强大的,因为它可以发送任何形式的数据(诸如纯文本,二进制码之类)。您需要做的只是在HTTP 请求header中设置满意的类型。但是,此servlet必须可以处理由applet发送的此类型的数据。
下面的代码片段显示了如何发送方法POST到一个servlet URL。
// 连接servlet
String location = "http://www.foo.com/servlet/TestServlet";
URL testServlet = new URL( servletLocation );
URLConnection servletConnection = testServlet.openConnection(); // 通知此连接我们将要发送output并且要接收input
servletConnection.setDoInput(true);
servletConnection.setDoOutput(true);//不能使用URL connection的缓存。
servletConnection.setUseCaches (false);
servletConnection.setDefaultUseCaches (false);// 指定我们将要发送的数据内容的类型为binary数据
servletConnection.setRequestProperty
("Content-Type", "<insert favorite mime type>");// 从servlet上取得input和output streams
. . .// 将您的数据发送到servlet
. . .
import java.io.*;
import java.applet.applet;
import java.awt.*;public class TestDataStreamApplet extends applet{
String response;
public void init(){
java.net.URL url=new java.net.URL(getDocumentBase(),"servlet/DataStreamEcho");
java.net.URLConnection con=url.openConnection();
con.serUseCaches(true);
con.setDoOutput(true);
con.setDoInput(true);
ByteArrayOutputStream byteout=new ByteArrayOutputStream();
DataOutputStream out=new DataOutputStream(byteout);
out.writeUTF("Hello world!");
out.flush();
byte buf[]=byteout.toByteArray();
con.setRequestProperty("Content-type","application/octest-stream");
con.setRequestProperty("Content-length",""+buf.length);
DataOutputStream dataout=new DataOutputStream(con.getOutputStream());
dataout.write(buf);
dataout.flush();
data.close(0;
DataInputStream in=new DataInputStream(con.getInputStream());
response=in.readUTF();
System.out.println("read from server:"+response);
in.close();
}catch(Exception e){
e.printStackTrace();
}
}
public void paint(Graphics g){
g.drawString("read from server:"+response,10,20);
}
}
servlet sourceimport javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;public class DataStreamEcho extends HttpServlet{
public void service(HttpServletRequest req.HttpServletResponse resp)
throws ServletException,java.io.IoException{
DataInputStream in=new DataInputStream(req.getInputStream());
resp.setContentType("application/octest-stream");
ByteArrayOutputStream byteout=new ByteArrayOutputStream();
DataOutputStream out=new DataOutputStream(byteout);
String response=in.readUTF();
out.writeUTF(response);
out.flush();
byte buf[]=byteout.toByteArray();
resp.setContentLength(buf.length);
ServletOutputStream servletout=resp.getOutputStream();
setvletout.write(buf);
servletout.close();
}
}
你上面说的第二种方法(用java.net包建立双向通讯)能不能给我一个完整的例子?
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType(CONTENT_TYPE);
try{
ObjectInputStream in=new ObjectInputStream(request.getInputStream());
String query_str=in.readObject().toString(); DataSource ds=new DataSource();
ds.readConfigData();
ds.open();
Query query=new Query();
query.setDataSource(ds);
query.executeQuery(query_str); response.setContentType("application/octest-stream");
ObjectOutputStream out=new ObjectOutputStream(response.getOutputStream());
out.writeObject(query.columnNames);
out.writeObject(query.table);
String path=this.getServletConfig().getServletContext().getRealPath("/images/exc.gif");
System.out.println(path);
ImageIcon img=new ImageIcon(path);
out.writeObject(img);
out.flush();
out.close();
query.close();
}catch(Exception e){
System.out.println("error:"+e.getMessage());
}
}applet:
try{
URL url=new URL(getDocumentBase(),"/servlet/qqpack.qqServlet");
URLConnection con=url.openConnection();
con.setUseCaches(true);
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestProperty("Content-type","application/octest-stream");
ObjectOutputStream out=new ObjectOutputStream(con.getOutputStream());
out.writeObject("select * from staticdb..deviceinfo");
out.flush();
out.close();
ObjectInputStream in=new ObjectInputStream(con.getInputStream());
Vector col=(Vector)in.readObject();
Vector data=(Vector)in.readObject();
ImageIcon img=(ImageIcon)in.readObject();
in.close();
//888888888888888888
for(int i=0;i<data.size();i++){
String name=((Vector)data.elementAt(i)).elementAt(1).toString().trim().toUpperCase();
ObjectButton jButton=new ObjectButton(img.getImage(),name);
jPanel1.add(jButton);
}
jPanel1.add(new LineButton("aaaaaaaa"));
jPanel1.updateUI();
}catch(Exception ee){
System.out.println("error:"+ee.getMessage());
}
作 者:FJY168
所
??
请给我你的MAIL
[email protected]