`

使用 Java applet 访问远程 Web 服务

阅读更多

通过浏览器提交、接收和分析 XML Web 服务消息

 
 
<script type="text/javascript"></script> <noscript></noscript> <script type="text/javascript"></script> <noscript></noscript>
 

 

<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- this content will be automatically generated across all content areas --><!--END RESERVED FOR FUTURE USE INCLUDE FILES-->

级别: 中级

Nicholas Chase (nicholas@nicholaschase.com), 开放源代码开发和分析人员, Studio B

2004 年 10 月 01 日

Applet 被设计成在“沙箱”中运行,不会对用户系统造成任何损害,因此其安全性要高于基于服务器的应用程序对等物。比方说,Java? 应用程序很容易让其他服务器的网络连接请求 Web 服务响应,applet 也能做到,只不过只能和最初发起的服务器对话。但是如果希望 applet 能够发出任意的 Web 请求,该怎么办呢?本文说明如何通过建立基于服务器的代理来解决这个问题。它还说明了如何使用 JavaScript 代码访问基于 applet 的信息。
<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES-->

本文将介绍如何创建一个系统,从而可以使用浏览器请求和交互任意来源的 Web 服务数据。首先创建一个基本的 applet,然后再创建从 Web 页面中提取数据的 JavaScript 代码,最后创建一个 servlet 作为非本地请求的代理。

本文假设您熟悉 Java 技术和(初步了解)XML。除了 J2SE 1.4 或更高版本这样的 Java 开发环境之外,本文还需要用到几个软件。为了发送和接收 SOAP 消息,您需要 SOAP with Attachments Application Program Interface (API) for Java(SAAJ,关于如何设置它,请参阅“ Send and receive SOAP messages with SAAJ”),以及 servlet 引擎,如 IBM? WebSphere? Application Server 或者 Apache Tomcat 来运行 servlet。关于所需各种软件包的链接,请参阅 参考资料

一个简单的请求

首先看一看最终由 applet 发出的请求。虽然这项技术适用于任何能够通过 URL 传递的数据,但本文主要讨论 Web 服务,因此我们从一个简单的 SOAP 消息开始,如清单 1 所示。


清单 1. 一个简单的 SOAP 消息
<SOAP-ENV:Envelope 
               SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:ns1="urn:chaosmagnet-quote"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body>
      <ns1:getQuoteResponse>
         <return xsi:type="xsd:string">The early bird gets the worm, but it's the 
second mouse that gets the cheese...</return>
      </ns1:getQuoteResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

该消息允许您创建一个简单的 Java 应用程序(清单 2)来检索和解析该 URL。

清单 2. 通过 Java 应用程序访问 URL

import java.net.URLConnection;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
public class SendRequest {
  public static void main(String args[]){
     try{
        URL url = new URL("http://www.nicholaschase.com/testsoap.php");
        URLConnection urlconn = url.openConnection();
        Document doc = null;
        try {
           DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
           DocumentBuilder db = dbf.newDocumentBuilder();
           doc = db.parse(urlconn.getInputStream());
           System.out.println(doc.getDocumentElement()
                .getFirstChild().getNextSibling()
                .getFirstChild().getNextSibling()
                .getFirstChild().getNextSibling().getFirstChild().getNodeValue());
        } catch (IOException e) {
           System.out.println("can't find the file:"+e.getMessage());
        } catch (Exception e) {
           System.out.print("Problem parsing the XML.");
        }
     } catch (Exception e){
        e.printStackTrace();
     }
  }
}

 

签名 applet 和未签名 applet

通常,applet 只能与有限的几台服务器建立连接。为了绕开这一限制,applet 需要进行数字签名。这样做虽然避开了限制,但是会造成浏览器弹出告警对话框,询问用户是否接受该签名。如果认为用户会对此类警告感到担忧,最好像下面这样来避开这一限制。

首先,创建真正的 URLConnection 。在此,需要把 InputStream 提供给 DocumentBuilder ,作为构造 Document 对象的来源。我发现输出语句不是很好,但本文主要讨论如何访问数据而不是分析数据,所以我就采用了直接引用的方法。

编译该程序然后在命令行中运行就可以得到预期的结果:

The early bird gets the worm, but it's the second mouse that gets the cheese...

 

您可能奇怪我为何宁愿这么麻烦地直接处理 XML,而不去使用(比方说)SAAJ。这是因为最终要把这些代码打包成一个 applet,它要在我无法控制的计算机上运行,因此希望坚持使用作为 Java 技术本身一部分的类。

创建 applet

applet 本身很简单,如清单 3 所示:


清单 3. 一个简单的 applet

import java.applet.*;
import java.awt.*;
public class SendRequest extends Applet {
  public void paint(Graphics g) {
      g.drawRect(0, 0, 499, 149);
      g.drawString("Printing...", 5, 70);
  }
}

每次打开这个 applet 时,applet 都仅仅绘制一个矩形,并在其中显示“Printing...”。保存并编译这个类,然后打开第二个文本文件创建来显示这个 applet 的 HTML 页面,如清单 4 所示。


清单 4. 显示 applet 的 HTML 页面

<HTML>
<HEAD>
   <TITLE>A Simple Program</TITLE>
</HEAD>
<BODY>
   <CENTER>
      
        
        <APPLET CODE="SendRequest.class" WIDTH="500" HEIGHT="150">
      </APPLET>
   </CENTER>
</BODY>
</HTML>
      
      

注意,通常 HTML 页面都包含用来调用 applet 代码的 APPLET 标签。将该 HTML 页面保存到 SendRequest.class 文件所在的目录中,然后在浏览器中打开它。您应该看到与图 1 类似的结果。


图 1. 简单的 applet
图 1. 简单的 applet

现在添加检索 URL 的代码。

 




回页首

 

从 applet 中访问响应

在 applet 中添加检索 URL 的代码很简单,如清单 5 所示。


清单 5. 在 applet 中添加检索 URL 的代码

import java.applet.*;
import java.awt.*;
import java.net.URLConnection;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
public class SendRequest extends Applet {
  public void paint(Graphics g) {
     g.drawRect(0, 0, 499, 149);
     g.drawString(
        
        getResponseText(), 5, 70);
  }
  
        
        public String getResponseText(){
    try{
      URL url = new URL("http://www.nicholaschase.com/testsoap.php");
      URLConnection urlconn = url.openConnection();
      Document doc = null;
      try {
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
       DocumentBuilder db = dbf.newDocumentBuilder();
       doc = db.parse(urlconn.getInputStream());
       return (doc.getDocumentElement()
            .getFirstChild().getNextSibling()
            .getFirstChild().getNextSibling()
            .getFirstChild().getNextSibling()
               .getFirstChild().getNodeValue());
      } catch (Exception e) {
       return "Can't get the string.";
      }
    } catch (Exception e){
      return "Problem accessing the response text.";
    }
  }
}
      
      

这里包含了大量原来应用程序中的代码,只是将 main() 方法改成了 getResponseText() 方法,并在浏览器显示 applet 时输出到页面中。

一切都准备就绪,但在刷新页面时,会看到情况并非如此,如图 2 所示。(要看到变化,必须在刷新页面时按下 Ctrl键)。


图 2. 从本地文件系统中调用 applet
图 2. 从本地文件系统中调用 applet

那么,问题出在哪儿呢?前面已经提到,applet 在设计时有一些安全性限制,其中之一就是不能访问服务器,但是不包括最初下载 applet 的服务器。因此,为了从 www.nicholaschase.com 上请求 URL,只需要把 applet 和 HTML 文件上传到那台服务器上。然后再调用 applet,就能得到预期的结果,如图 3 所示。


图 3. 从适当的服务器上访问 applet
图 3. 从适当的服务器上访问 applet

现在已经获得了数据,可以从 HTML 页面中访问了。

 




回页首

 

通过 JavaScript 访问 applet 数据

这个过程的最终目标是使用 JavaScript 代码分析检索的数据。其中的关键是将 applet 看作一个对象,事实上, APPLET 标签最后将被替换为 object 标签。为了替换标签,必须为其指定 id 属性,如清单 6 所示。


清单 6. 作为对象访问 applet

<HTML>
<HEAD>
   <TITLE>A Simple Program</TITLE>
</HEAD>
<BODY>
   <CENTER>
      <APPLET CODE="SendRequest.class" WIDTH="500" HEIGHT="150" id="TheApplet">
      </APPLET>
   </CENTER>
        
           <b>The returned data is:</b><br />
   <script type="text/javascript">
      document.write(TheApplet.getResponseText());
   </script>
</BODY>
</HTML>
      
      

为 applet 指定一个 id 属性,从而能够将其作为简单的对象处理,并且可以直接调用 applet 的方法。如果保存该页面并刷新它,就会看到从页面中提取的信息(参见图 4)。


图 4: 通过 JavaScript 访问 applet 数据
图 4:  通过 JavaScript 访问 applet 数据

现在就只剩下能够访问任意 URL 的问题了。

 




回页首

 

创建代理

现在万事俱备,但是因为安全性要求,您只能访问下载 applet 的服务器。如何才能访问不同的服务器呢?

比方说,假设要从 Quote of the Day service 获得实时报价。由于 applet 只能连接到自己的服务器,所以您就不能直接连接到 applet。但是服务器可以连接任何事物,就是说除了直接连接到数据,您还可以连接到检索数据的 servlet。

清单 7 中的代码创建了一个从 Quote of the Day service 中检索响应的 servlet。


清单 7. 检索远程信息的 servlet

import javax.servlet.http.*;
import javax.servlet.*;
 
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamResult;
public class SendingServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
                                         throws ServletException {
    try {
     
       //First create the connection
       SOAPConnectionFactory soapConnFactory = 
                      SOAPConnectionFactory.newInstance();
       SOAPConnection connection = 
                        soapConnFactory.createConnection();
         
       //Next, create the actual message
       MessageFactory messageFactory = MessageFactory.newInstance();
       SOAPMessage message = messageFactory.createMessage();
         
       //Create objects for the message parts            
       SOAPPart soapPart =     message.getSOAPPart();
       SOAPEnvelope envelope = soapPart.getEnvelope();
       SOAPBody body =         envelope.getBody();
       //Populate the body
       //Create the main element and namespace
       SOAPElement bodyElement = 
           body.addChildElement(envelope.createName("getQuote" , 
                                     "ns1", 
                                     "urn:xmethods-qotd"));
       //Save the message
       message.saveChanges();
       //Send the message and get a reply   
            
       //Set the destination
       String destination = 
              "http://webservices.codingtheweb.com/bin/qotd";
       //Send the message
       SOAPMessage reply = connection.call(message, destination);
       //Check the output
       //Create the transformer
       TransformerFactory transformerFactory = 
                         TransformerFactory.newInstance();
       Transformer transformer = 
                       transformerFactory.newTransformer();
       //Extract the content of the reply
       Source sourceContent = reply.getSOAPPart().getContent();
       resp.setHeader("Content-Type", "text/plain");
       //Set the output for the transformation
       StreamResult result = new StreamResult(resp.getWriter());
       transformer.transform(sourceContent, result);
       //Close the connection            
       connection.close();
            
     } catch(Exception e) {
      System.out.println(e.getMessage());
     }
  }
}

这段脚本看起来又长又复杂,但实际上非常简单。它首先创建 SOAPConnection 和消息对象,然后根据 Quote of the Day service 的要求使用 getQuote 元素填充该对象。

创建完成请求消息之后,将其发送到服务并检索答复。将答复作为 SOAPMessage 对象返回,但是您需要把消息的实际文本传递给 servlet 的 Response 对象。为此,只需要使用以响应为目标的 XSLT 恒等转换。

编译上述 servlet,并按照一般的 servlet 方式安装它(如果需要帮助,请参阅 参考资料),然后就可以直接从浏览器中调用它,并看到图 5 所示的结果。


图 5: 本地 servlet 检索得到的远程响应
图 5: 本地 servlet 检索得到的远程响应

现在,把远程信息放到 applet 中就与调用 servlet 一样简单了,如清单 8 所示:


清单 8. 从 applet 中调用远程数据

...
  public void paint(Graphics g) {
      g.drawRect(0, 0, 499, 149);
      g.drawString(getResponseText(), 5, 70);
  }
  public String getResponseText(){
     try{
        URL url = new URL("
        
        http://localhost:8080/servlet/SendingServlet");
        URLConnection urlconn = url.openConnection();
        Document doc = null;
        try {
           DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
           DocumentBuilder db = dbf.newDocumentBuilder();
           doc = db.parse(urlconn.getInputStream());
  
           return (doc.getDocumentElement()
 
        
                          .getFirstChild().getFirstChild().getFirstChild()
                   .getFirstChild().getNodeValue()); 
        } catch (Exception e) {
           return "Can't get the string:"+e.toString();
        }
     } catch (Exception e){
        return "Problem accessing the response text."+e.toString();
     }
  }
}
      
      

注意,这里的代码基本上是相同的,只有两个地方不一样。首先,这里没有直接调用数据,而是调用检索数据的 servlet。其次,因为服务返回的消息没有断行,所以在这里稍微整理了一下。

如需查看结果,可以将 applet 和 HTML 页面复制到安装 serlevt 的服务器上,然后就可以访问 applet 并察看结果了,如图 6 所示。


图 6: 查看结果
图 6: 查看结果




回页首

 

结束语

本文介绍了如何创建一个系统,可以使浏览器访问任意的 Web 服务。JavaScript 代码在 applet 中调用了一个方法,而 applet 又调用了检索远程信息的 servlet,这样就避开了 applet 访问能力的限制。

现在,您可以从几个方面来理清整个过程或者增强其功能。因为数据是被拖放入 JavaScript 代码中的,所以您不需要在页面上显示真正的 applet。您还可以修改 applet,从服务中检索多条信息,或者在单个请求中传回信息,而不必在每次用户更改窗口时发送新的请求。

如果想更进一步,还可以修改 servlet 的选项,使它从 applet 中获取参数。这些参数可以决定 servlet 调用什么服务,或者传递给服务什么参数。使用这些方法(如本文中的 getResponseText() ),您甚至可以编写 JavaScript 代码,将这些参数导入 applet,让用户决定最终显示什么信息。

 

关于作者

 

 

Nicholas ChaseStudio B的作者,曾参与过许多公司网站的开发,其中包括 Lucent Technologies、Sun Microsystems、Oracle 和 Tampa Bay Buccaneers。Nick 曾经做过高中物理教师、低级放射性废弃设备管理员、在线科幻杂志的编辑、多媒体工程师以及 Oracle 教员。最近,他在担任美国佛罗里达州克利尔沃特市一家交互通信公司的首席技术官,同时,他还是几本介绍 XML 和 Web 开发的书籍的作者,其中包括 XML Primer Plus ( Sams)。目前,他正准备购买一座农场,打算和妻子饲养羊驼和小鸡。他很想听到读者的意见,您可以通过 nicholas@nicholaschase.com 与他联系。

分享到:
评论

相关推荐

    javaapplication和javaapplet的区别

    - 通过使用Java Applet,开发者可以创建更丰富、更动态的Web体验。 #### 四、执行方面的区别 - **运行位置**:Java Application通常在本地机器上运行,而Java Applet则通常部署在远程服务器上,根据客户端的请求...

    java Application与java Applet的区别

    Java Application适合创建独立运行的复杂应用,而Java Applet则专注于网页增强,提供多媒体效果和交互性,尽管随着Web技术的发展,如JavaScript和HTML5的兴起,Java Applet的使用已逐渐减少,但它在Web发展史上的...

    基于VC++ 和Java Applet 远程医疗终端系统

    在远程医疗场景中,Java Applet可能用于实现跨平台的Web应用,比如医生可以通过浏览器上的Applet访问患者数据,进行在线诊断。Java Applet的安全性、跨平台性和动态加载能力使其成为构建网络应用的理想选择,尽管...

    远程采集系统嵌入式WEB端java applet动态曲线显示采集量的代码.zip

    本项目“远程采集系统嵌入式WEB端java applet动态曲线显示采集量的代码”正是这样的一个解决方案,它利用Java Applet技术在Web页面上实现了动态曲线的展示,从而可视化地展示远程采集到的数据。 Java Applet是Java...

    Java Applet在WWW上的应用

    8. **实际应用**:尽管Java Applet的使用已经减少,但在某些领域,如教育软件、在线游戏、远程桌面等,仍然可以看到其应用。理解Applet的工作原理有助于开发者更好地理解现代Web技术的发展历程。 总之,深入学习...

    java applet运行出现异常

    Java Applet是Java技术在早期Web应用中的一种实现方式,它允许开发者在浏览器中嵌入小型的Java程序,提供交互式和动态的功能。然而,由于安全性和现代Web开发趋势的改变,Applet已经逐渐被淘汰,被更现代的技术如...

    阳光酒店管理系统(javaapplet+SQL).zip

    通过使用Java Applet,系统可以在Web浏览器中运行,便于远程访问和跨平台操作。 Java Applet是Java语言的一个子集,主要用于创建能在Web浏览器中执行的小程序。在这个酒店管理系统中,Java Applet作为前端界面,...

    第八章Applet应用程序(java)

    总体而言,Java Applet是Java语言在Web应用中嵌入式技术的一种实现方式,它为互联网上的小程序提供了平台,使得用户可以在网页中直接运行Java程序。然而,随着技术的发展,尤其是在移动互联网和现代Web应用的兴起下...

    基于JavaApplet的可变情报板监控软件.pdf

    "基于JavaApplet的可变情报板监控软件" 该软件系统是基于Java Applet的可变情报板监控软件,用户可以通过浏览器远程登录目标情报板设备,下载并运行Applet监控软件,然后通过操作该软件对目标情报板上的应用程序...

    让WEB服务器从视频服务器获取数据流的JAVA源程序

    这种技术通常用于构建分布式多媒体系统,使得用户可以通过Web浏览器访问和观看远程视频服务器上的实时或录播视频。 在描述中提到,当用户通过Web服务器访问时,可以查看到视频服务器捕获的视频图像。这表明该Java...

    web 扫描仪程序 applet

    3. **安全性**:Java的安全模型为Applet提供了沙箱环境,限制了Applet对本地系统的访问权限,这在一定程度上保证了使用Web扫描仪的用户的系统安全。 4. **网络通信**:Applet可以利用Java的网络类库与服务器进行...

    Applet Debug

    Applet是一种小型的Java程序,可以在Web浏览器中运行,但开发过程中可能会遇到各种问题,此时就需要进行调试。远程调试使得开发者能够在本地环境中对运行在远程服务器上的Applet进行调试,而无需在服务器上直接操作...

    基于Java的酒店管理系统(javaapplet+SQL).zip

    网络设置涉及系统的部署和远程访问配置,可能需要用到Java的网络编程技术。系统设置则可能包括权限管理、日志记录、系统参数调整等功能,体现了Java强大的面向对象设计和系统管理能力。 总结来说,这个基于Java的...

    基于matlab和Java Applet的数字化实验室研究.pdf

    基于Matlab和Java Applet的数字化实验室研究,主要涉及使用Java Applet技术与Matlab/Simulink结合来构建一种基于Web的数字化实验方法。这种结合方式可以实现数字化实验,并特别应用于数字电路的实验。以下是这项研究...

    基于Vxworks嵌入式web服务器的远程实时图形显示及控制系统

    文档详细介绍了在Vxworks嵌入式实时操作系统上实现远程实时图形显示及控制系统的原理和步骤,通过GoAhead WebServer作为Web服务的载体,利用Java Applet实现与用户的动态交互。该系统充分利用了Vxworks的实时处理...

    eftp(applet)

    标题 "eftp(applet)" 暗示我们讨论的是一个基于Java Applet技术实现的FTP客户端,用于在Web浏览器环境中进行文件传输。Applets是Java的一种早期特性,允许开发者创建可嵌入到HTML页面中的小型应用程序,使得用户可以...

    java-applet-soket-rmi.rar_websign.html

    1. **Java RMI的原理**:RMI使用接口定义服务,客户端通过引用远程对象的接口来调用其方法。这些调用会被转换为网络消息,由RMI运行时系统处理,然后在目标JVM上执行相应的方法。返回的结果再通过网络返回给客户端。...

    网页上Applet用javacomm20读取客户端串口

    标题中的“网页上Applet用javacomm20读取客户端串口”指的是在Web页面中使用Java Applet通过javacomm20这个库来访问客户端计算机的串行通信端口(COM口)。这通常用于实现远程控制、数据传输或者设备交互等应用场景...

    基于嵌入式Web服务器的远程实时数据采集.pdf

    本文主要探讨了一种基于CGI(通用网关接口)和Java Applet技术在嵌入式Web服务器上实现远程实时数据采集的方法。 CGI是一种标准,允许Web服务器与外部程序交互,从而扩展了Web服务器的功能。当用户在浏览器中请求...

    基于JAVACS远程监控系统软件的实现.pdf

    虽然在现代Web应用中Java Applet的使用已大大减少,文件中仍然提到了Java Applet和相关的网络编程技术。这可能表明在JAVACS远程监控系统中,有通过浏览器插件方式实现远程监控的组件,允许用户通过Web界面进行系统的...

Global site tag (gtag.js) - Google Analytics