现在的位置: 首页 > 综合 > 正文

[Google API](7)直接使用Web服务

2013年10月24日 ⁄ 综合 ⁄ 共 9659字 ⁄ 字号 评论关闭

到目前为止,本教程一直在讨论通过 Java 应用程序使用 API 来达到 Google Web 服务的使用目的,但这只是一种方便的办法。可以直接通过 SOAP 消息(在 http://api.google.com/search/beta2)使用服务本身。

SOAP 消息携带有关执行服务器端子程序的信息,参数在消息体内指定。服务器将发送一条 SOAP 消息作为响应,并在消息体内对信息进行编码。

然后,应用程序接收到响应,要么将其作为单独的信息处理,要么使用传统的 XML 方法对数据进行转换。

这一章将着眼于请求和响应 SOAP 消息和发送、接收消息的 JAXM 应用程序。(若想更多的了解使用 JAXM 发送、接收 SOAP 消息的信息,请参阅构建使用 Google API 的 Java 应用程序参考资料。)

  发送 SOAP 请求

首先,请看一个 JAXM 应用程序,它发送一条预先定义好的 SOAP 消息,并输出结果。

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 java.io.FileInputStream; 
import javax.xml.transform.stream.StreamSource; 
import javax.xml.messaging.URLEndpoint; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.Source; 
        
import javax.xml.transform.stream.StreamResult; 
        
public class GoogleSOAP { 
     
   public static void main(String args[]) {
         
      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();
        
         //Populate the Message
         StreamSource preppedMsgSrc = new StreamSource( 
                  new FileInputStream("search.msg"));
         soapPart.setContent(preppedMsgSrc);
        
         //Save the message
         message.saveChanges();
        
         //SEND THE MESSAGE AND GET A REPLY
             
         //Set the destination
         URLEndpoint destination = 
               new URLEndpoint("http://api.google.com/search/beta2");
         //Send the message
         SOAPMessage reply = connection.call(message, destination);
        
         //SAVE THE OUTPUT
        
         //Create the transformer
         TransformerFactory transformerFactory = 
                            TransformerFactory.newInstance();
         Transformer transformer = 
                         transformerFactory.newTransformer();
         //Extract the content of the reply
         Source sourceContent = reply.getSOAPPart().getContent();
        
         //Set the output for the transformation
         StreamResult result=new StreamResult("results.out");
         transformer.transform(sourceContent, result);
        
         //Close the connection            
         connection.close();
             
        } catch(Exception e) {
            System.out.println(e.getMessage());
        } 
    } 
}

这个应用程序首先创建了一个连接,然后是一个 SOAPMessage 对象。文件 search.msg 将填入消息的 SOAPPart,接着它会被发给 Google Web 服务。

以另外一条 SOAP 消息的形式,回复得以返回,它的相关信息在 SOAPPart 中。在这种情况下,实际上您并没有转换信息,而只是将 Transformer 用作序列化器把结果发给 results.out 文件。

在下几屏中,我会分析实际的消息。

  搜索请求

搜索请求 SOAP 消息包含的参数和以前 API 所设置的完全相同,不过,现在这些参数是 XML 元素:

<?xml version='1.0' encoding='UTF-8'?> 
<SOAP-ENV:Envelope  
          xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"  
          xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" 
          xmlns:xsd="http://www.w3.org/1999/XMLSchema">
   <SOAP-ENV:Body>
    <ns1: doGoogleSearch  xmlns:ns1="urn:GoogleSearch" 
         SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <key xsi:type="xsd:string">00000000000000000000000000000000</key>  <q xsi:type="xsd:string">"science fiction"</q> 
      <start xsi:type="xsd:int">0</start>
      <maxResults xsi:type="xsd:int">10</maxResults>
      <filter xsi:type="xsd:boolean">true</filter>
      <restrict xsi:type="xsd:string"></restrict>
      <safeSearch xsi:type="xsd:boolean">false</safeSearch>
      <lr xsi:type="xsd:string"></lr>
      <ie xsi:type="xsd:string">latin1</ie>
      <oe xsi:type="xsd:string">latin1</oe>
    </ns1: doGoogleSearch > 
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

请注意,doGoogleSearch 这个方法名是在消息内指定的,而且列出了每个参数,即使是空值的参数。这与执行以下的方法是一样的:

doGoogleSearch("", ""science fiction"", 0, 10, true, "", false, "", "latin1",
"latin1")

  搜索结果

结果 XML 文件携带的信息和 API 所提取的一样。以下所示的部分结果添加了一些空格以增加其易读性。

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body> 
<ns1:doGoogleSearchResponse  
     xmlns:ns1="urn:GoogleSearch" 
     SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
   <return xsi:type="ns1:GoogleSearchResult">
      <documentFiltering xsi:type="xsd:boolean">false</documentFiltering>
      <estimatedTotalResultsCount xsi:type="xsd:int">
      1500000</estimatedTotalResultsCount>
      <directoryCategories 
             xmlns:ns2="http://schemas.xmlsoap.org/soap/encoding/" 
             xsi:type="ns2:Array" 
             ns2:arrayType="ns1:DirectoryCategory[0]">
      </directoryCategories>
      <searchTime xsi:type="xsd:double">0.060022</searchTime>
      <resultElements 
              xmlns:ns3="http://schemas.xmlsoap.org/soap/encoding/" 
              xsi:type="ns3:Array" ns3:arrayType="ns1:ResultElement[10]">
         <item xsi:type="ns1:ResultElement">
            <cachedSize xsi:type="xsd:string">29k</cachedSize>
            <hostName xsi:type="xsd:string"/>
            <snippet xsi:type="xsd:string"> 
                 &lt;b&gt;...&lt;/b&gt; After a long career creating superior 
                 &lt;b&gt;science&lt;/b&gt;-&lt;b&gt;fiction&lt;/b&gt; TV, 
                 writer/producer David Kemper&lt;br&gt; reflects on the finale of
                 Farscape's current season and his startling &lt;b&gt;...&lt;/b&gt;
            </snippet>
            <directoryCategory xsi:type="ns1:DirectoryCategory">
               <specialEncoding xsi:type="xsd:string"/>
               <fullViewableName 
                    xsi:type="xsd:string">Top/Arts/Literature/Genres/Science_Fiction
                    /Magazines_and_E-zines</fullViewableName>
            </directoryCategory>
            <relatedInformationPresent xsi:type="xsd:boolean">
                true
            </relatedInformationPresent>
            <directoryTitle xsi:type="xsd:string">
                 &lt;b&gt;Science&lt;/b&gt; &lt;b&gt;Fiction&lt;/b&gt; Weekly 
            </directoryTitle>
            <summary xsi:type="xsd:string">
                  The leading electronic publication covering the world of 
                  &lt;b&gt;Science&lt;/b&gt; &lt;b&gt;Fiction&lt;/b&gt;, with news,
                  reviews, original... 
            </summary>
            <URL xsi:type="xsd:string">http://www.scifi.com/sfw/</URL>
            <title xsi:type="xsd:string">
                  &lt;b&gt;Science&lt;/b&gt; &lt;b&gt;Fiction&lt;/b&gt; Weekly
            </title>
         </item>
... 
      </resultElements>
      <endIndex xsi:type="xsd:int">10</endIndex>
      <searchTips xsi:type="xsd:string"/>
      <searchComments xsi:type="xsd:string"/>
      <startIndex xsi:type="xsd:int">1</startIndex>
      <estimateIsExact xsi:type="xsd:boolean">false</estimateIsExact>
      <searchQuery xsi:type="xsd:string">
           &amp;quot;science fiction&amp;quot;
      </searchQuery>
   </return>
</ns1:doGoogleSearchResponse> 
        
</SOAP-ENV:Body> 
</SOAP-ENV:Envelope>  

请注意,API 检索到的每条信息都可以在 XML 元素中使用。

  转换结果

利用结果与为将结果转换为需要的格式而创建一个样式表都很简单。例如,简单的样式表能提取站点标题和 URL:

<?xml version="1.0"?> 
        
<xsl:stylesheet  
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        
<xsl:output method="text"/> 
        
<xsl:template match="/"> 
<xsl:apply-templates select="//item"/> 
</xsl:template> 
        
<xsl:template match="item"> 
  <xsl:value-of select="title"disable-output-escaping="yes"/><xsl:text>
  </xsl:text><xsl:value-of select="URL"/><xsl:text>
       
</xsl:text> 
</xsl:template> 
        
</xsl:stylesheet>

接下来应用程序将调用该样式表……

... 
         //Create the transformer
         TransformerFactory transformerFactory = 
                            TransformerFactory.newInstance();
          Source styleSheet = new StreamSource("translate.xsl");   
         Transformer transformer = 
                         transformerFactory.newTransformer( styleSheet );
         //Extract the content of the reply
         Source sourceContent = reply.getSOAPPart().getContent();
        
         //Set the output for the transformation
         StreamResult result=new StreamResult("results.out");
         transformer.transform(sourceContent, result);
...

……得到的是格式很规范的结果:

<b>Science</b> <b>Fiction</b> Weekly

http://www.scifi.com/sfw/

SCIFI.COM 

http://www.scifi.com/

<b>Science</b> <b>Fiction</b> and Fantasy Writers of America, Inc.

http://www.sfwa.org/

The Link ping <b>Science</b> <b>Fiction</b> &amp; Fantasy Archive

http://www2.lysator.liu.se/sf_archive/

...

请注意这只是很简单的示例。您可以使用 XSLT 来提取,甚至处理数据以使其可以包括在数据库和其它系统中,并使其可以为其它应用程序所用。

  拼写请求

拼写建议的 SOAP 消息很直观。

请求:

<?xml version='1.0' encoding='UTF-8'?> 
<SOAP-ENV:Envelope  
       xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
       xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" 
       xmlns:xsd="http://www.w3.org/1999/XMLSchema">
  <SOAP-ENV:Body> 
    <ns1:doSpellingSuggestion 
        xmlns:ns1="urn:GoogleSearch"
        SOAP-ENV:encodingStyle=
               "http://schemas.xmlsoap.org/soap/encoding/">
      <key xsi:type="xsd:string">00000000000000000000000000000000</key>
      <phrase xsi:type="xsd:string">scince</phrase> 
    </ns1:doSpellingSuggestion>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

结果:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"xmlns:xsd=
"http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body> 
<ns1:doSpellingSuggestionResponse xmlns:ns1="urn:GoogleSearch" 
         SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<return xsi:type="xsd:string">science</return> 
</ns1:doSpellingSuggestionResponse> 
        
</SOAP-ENV:Body> 
</SOAP-ENV:Envelope>


  缓存请求

由于响应是以 base64 返回的,所以缓存请求有点复杂。请求:

<?xml version='1.0' encoding='UTF-8'?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"xmlns:xsd=
"http://www.w3.org/1999/XMLSchema">
  <SOAP-ENV:Body>
    <ns1:doGetCachedPage xmlns:ns1="urn:GoogleSearch" 
        SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <key xsi:type="xsd:string">181gQtaOdlLD+83qvh6PnssQR5WlaB9d</key>
      <url xsi:type="xsd:string"> 

http://www-106.ibm.com/developerworks/xml/library/x-tiphdln.html

      </url> 
    </ns1:doGetCachedPage> 
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

生成结果:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" 
	xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body> 
<ns1:doGetCachedPageResponse xmlns:ns1="urn:GoogleSearch"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<return xmlns:ns2="http://schemas.xmlsoap.org/soap/encoding/"
xsi:type="ns2:base64">PG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50
PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9SVNPLTg4NTktMSI+CjxCQVNFIEhSRUY9Imh0dHA6Ly93d3ctMTA
2LmlibS5jb20vZGV2ZWxvcGVyd29ya3MveG1sL2xpYnJhcnkveC10aXBoZGxuLmh0bWwiPjx0YWJsZSBib
3JkZXI9MSB3aWR0aD0xMDAlPjx0cj48dGQ+PHRhYmxlIGJvcmRlcj0xIGJnY29sb3I9I2ZmZmZmZiBjZW
xscGFkZGluZz0xMCBjZWxsc3BhY2luZz0wIHdpZH...
ZT4NCjwhLS0gRU5EIElCTSBGT09URVIgLS0+PC9ib2R5Pgo8L2h0bWw+Cg==</return> 
</ns1:doGetCachedPageResponse> 
        
</SOAP-ENV:Body> 
</SOAP-ENV:Envelope>

请务必相应调整您的应用程序,否则就请直接用 API 自动执行翻译。

 

抱歉!评论已关闭.