이 문서에서는 브라우저를 사용하여 모든 소스의 웹 서비스 데이터를 요청하고 상호 작용할 수 있는 시스템을 만드는 방법을 설명합니다. 기본 애플릿을 생성하는 것으로 시작한 다음 웹 페이지에서 데이터를 추출하기 위한 JavaScript 코드를 생성하고 마지막으로 로컬이 아닌 요청에 대한 프록시 역할을 하는 서블릿을 생성합니다.
이 글에서는 귀하가 Java 기술 및 XML(기본 지식)에 익숙하다고 가정합니다. 이 기사에는 J2SE 1.4 이상과 같은 Java 개발 환경 외에도 여러 소프트웨어가 필요합니다. SOAP 메시지를 보내고 받으려면 Java용 첨부 API(Application Program Interface)가 포함된 SOAP(SAAJ, 설정 방법은 "SAAJ를 사용하여 SOAP 메시지 보내기 및 받기" 참조) 및 IBM과 같은 서블릿 엔진이 필요합니다. ? WebSphere® 애플리케이션 서버 또는 Apache Tomcat을 사용하여 서블릿을 실행합니다.
간단한 요청
먼저 애플릿의 최종 요청을 살펴보세요. 이 기술은 URL을 통해 전달될 수 있는 모든 데이터에 적용되지만 이 기사에서는 웹 서비스에 중점을 두므로 목록 1에 표시된 대로 간단한 SOAP 메시지부터 시작하겠습니다.
목록 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(); } } }
먼저 실제 URLConnection을 만듭니다. 여기에서 Document
객체를 구성하는 의 소스로 DocumentBuilder에 InputStream을 제공해야 합니다. 출력문이 별로 좋지 않다는 것을 알았으나, 이번 글에서는 데이터 분석
보다는 데이터에 접근하는 방법을 주로 다루기 때문에 직접 인용하는 방식을 채택했습니다.
이 프로그램을 컴파일하고 명령줄에서 실행하면 예상한 결과를 얻을 수 있습니다.
The early bird gets the worm, but it's the second mouse that gets the cheese...
왜 내가 XML을 사용하는 대신 XML을 직접 처리하는 수고를 하겠는지 궁금할 것입니다. ) SAAJ. 이는 궁극적으로 이 코드를 내가 제어할 수 없는 컴퓨터에서 실행되는 애플릿으로 패키징하고 싶기 때문에 Java 기술 자체의 일부인 클래스를 고수하고 싶기 때문입니다.
애플릿 만들기
목록 3에 표시된 것처럼 애플릿 자체는 매우 간단합니다.
목록 3. 간단한 애플릿
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); } }
애플릿이 열릴 때마다 애플릿은 단순히 직사각형을 그리고 그 안에 "인쇄 중..."을 표시합니다. 이 클래스를 저장하고 컴파일한 다음 목록 4와 같이 애플릿의 HTML 페이지를 표시하기 위해 생성된 두 번째 텍스트 파일을 엽니다.
목록 4. 애플릿을 표시하는 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 태그가 포함되어 있습니다. SendRequest.class 파일과 동일한 디렉터리에 HTML 페이지를 저장하고 브라우저에서 엽니다. 그림 1과 비슷한 결과가 표시됩니다.
그림 1. 간단한 애플릿
이제 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
那么,问题出在哪儿呢?前面已经提到,applet 在设计时有一些安全性限制,其中之一就是不能访问服务器,但是不包括最初下载 applet 的服务器。因此,为了从 www.nicholaschase.com 上请求 URL,只需要把 applet 和 HTML 文件上传到那台服务器上。然后再调用 applet,就能得到预期的结果,如图 3 所示。
图 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 数据
现在就只剩下能够访问任意 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 检索得到的远程响应
现在,把远程信息放到 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: 查看结果
结束语
本文介绍了如何创建一个系统,可以使浏览器访问任意的 Web 服务。JavaScript 代码在 applet 中调用了一个方法,而 applet 又调用了检索远程信息的 servlet,这样就避开了 applet 访问能力的限制。
现在,您可以从几个方面来理清整个过程或者增强其功能。因为数据是被拖放入 JavaScript 代码中的,所以您不需要在页面上显示真正的 applet。您还可以修改 applet,从服务中检索多条信息,或者在单个请求中传回信息,而不必在每次用户更改窗口时发送新的请求。
如果想更进一步,还可以修改 servlet 的选项,使它从 applet 中获取参数。这些参数可以决定 servlet 调用什么服务,或者传递给服务什么参数。使用这些方法(如本文中的 getResponseText() ),您甚至可以编写 JavaScript 代码,将这些参数导入 applet,让用户决定最终显示什么信息。
【相关推荐】
1. 特别推荐:“php程序员工具箱”V0.1版本下载
2. Java免费视频教程
5. Applet과 Applet의 차이점을 자세히 설명하세요
위 내용은 브라우저가 웹 서비스에 액세스할 수 있도록 애플릿을 사용하여 시스템을 만드는 방법을 가르칩니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!