在java中"模拟" XMLHttpRequest

28 篇文章 0 订阅
关键字: java, ajax, xmlhttprequest
这里所说的"模拟" 是指 : 在java中,使用类似 XMLHttpRequest 的方式来实现"同步/异步的HttpRequest"功能.


  用 java 实现一个HTTPRequest 并不难. 通过 java.net 包内提供的东东 可以很容易的实现.
  而且我们还有 apache 的 HttpClient 一类的组件可供我们使用 .
  实现 异步的HTTPRequest 当然同样简单 , 再使用一个 Thread就ok了.
  但是 使用上面的 方法 , 实现的往往只是一个 "异步的HTTPRequest"的功能而已,
  使用方式上 还是 很 java的.
 
我在这里所要介绍的 则是使用很"ajax"的方式来实现"异步的HTTPRequest"的功能.
这个 AjaxHttpRequest 类  模仿了 XMLHttpRequest 的实现,
从属性 方法 使用方式上 都尽量的和 XMLHttpRequest 接近.

利用 AjaxHttpRequest 类 可以更自然的实现 ajax请求的服务端代理 等工作.

=============================

当然 本文的技术研究的价值 也许远远大于 实用的价值. :P .


我先来举一个例子 ,  AjaxHttpRequest 类的代码&注释 在后面附上 附件中也会提供该java文件.

大家注意看代码注释 ,我要说的东西更多的都在注释里呢.

一个 用 java 来调用 google 翻译服务的例子 (利用了后面附上的 AjaxHttpRequest 类) :

Java代码
  1. /**  
  2.  * 利用这个AjaxHttpReuqest类来实现 对google translate服务的访问 .  
  3.  * 只演示了 "英-->汉"的翻译.  
  4.  * 返回的是JSON字符串,需要使用Json工具类进行转换,这个不难 就不详细举例了.  
  5.  */  
  6. public static void testGoogleTranslate(String words,boolean async) throws IOException {   
  7.     Map params=new HashMap();   
  8.     params.put("q",words);   
  9.     params.put("v","1.0");   
  10.     params.put("langpair","en|zh-CN");   
  11.     String url="http://ajax.googleapis.com/ajax/services/language/translate";   
  12.        
  13.     // 以上为 调用google翻译服务所需要的参数.   
  14.     // 下面 是用java 来调用这个 翻译服务.   
  15.     // 在 AjaxHttpRequest 类的 帮助下 我们可以使用 类似操作浏览器XHR对象的方式来 实现该功能.   
  16.   
  17.        
  18.     // 创建 AjaxHttpRequest对象 相当于 创建 XHR对象.   
  19.     // 这里的final 主要是为了"使监听器内部能够调用ajax对象"而加的.   
  20.     final AjaxHttpRequest ajax=new AjaxHttpRequest();   
  21.        
  22.     // 设置状态监听器,类似 XHR对象的 onreadystatechange 属性.   
  23.     // 由于js 和java的本质区别 导致这里可能和 xhr有点不一样,但是应该不难理解.   
  24.     ajax.setReadyStateChangeListener(   
  25.             // 监听器, 根据需求 实现onReadyStateChange方法即可.   
  26.             new AjaxHttpRequest.ReadyStateChangeListener(){   
  27.                     public void onReadyStateChange() {   
  28.                         int readyState = ajax.getReadyState();   
  29.                         //判断状态 然后做出相应处理.   
  30.                         if (readyState==AjaxHttpRequest.STATE_COMPLETE){   
  31.                             System.out.println( ajax.getResponseText() );   
  32.                         }   
  33.                     }              
  34.             }   
  35.     );   
  36.        
  37.     // 这里就和 xhr 几乎完全一样了   
  38.     ajax.open("POST", url, true);   
  39.        
  40.     //这里这个send方法接受的参数是一个map ,当然AjaxHttpRequest类也提供了string的方法   
  41.     ajax.send(params);   
  42.   
  43. }  


有了上面的功能 当页面中要使用google的翻译服务时 就不用在引入google的那些js了.
也不用担心 客户端无法访问google的情况了.



下面附上 AjaxHttpRequest类 的完整代码 ( 附件中有下载 )

Java代码
  1. package com.fins.gt.server;   
  2.   
  3. import java.io.IOException;   
  4. import java.io.InputStream;   
  5. import java.io.OutputStream;   
  6. import java.io.UnsupportedEncodingException;   
  7. import java.net.HttpURLConnection;   
  8. import java.net.MalformedURLException;   
  9. import java.net.Proxy;   
  10. import java.net.URL;   
  11. import java.net.URLConnection;   
  12. import java.net.URLEncoder;   
  13. import java.util.HashMap;   
  14. import java.util.Iterator;   
  15. import java.util.LinkedHashMap;   
  16. import java.util.Map;   
  17. import java.util.StringTokenizer;   
  18. import java.util.logging.Level;   
  19.   
  20.            
  21. /**  
  22.  * AjaxHttpRequest ,用java 模拟 浏览器的 XMLHttpRequest 对象.  
  23.  * 目的是 用 操作浏览器中的XHR对象的 方式来处理java端的 http请求.  
  24.  *   
  25.  * @author fins  
  26.  *   
  27.  * 本类的实现借鉴了 cobra 组件的 org.lobobrowser.html.test.SimpleHttpRequest 类.  
  28.  * 可以看作是对 SimpleHttpRequest 类的一个完善和补充.  
  29.  *   
  30.  * cobra 组件是一个 Java HTML Renderer & Parser,  
  31.  * 官方网站 : http://lobobrowser.org/cobra.jsp  
  32.  */  
  33.   
  34. public class AjaxHttpRequest {   
  35.   
  36.     // 对应 XMLHttpRequest 的5种状态.   
  37.     public static final int STATE_UNINITIALIZED = 0;   
  38.     public static final int STATE_LOADING = 1;   
  39.     public static final int STATE_LOADED = 2;   
  40.     public static final int STATE_INTERACTIVE = 3;   
  41.     public static final int STATE_COMPLETE = 4;   
  42.   
  43.     // 默认的 userAgent    
  44.     public static final String DEFAULT_USERAGENT = "Mozilla/4.0 (compatible; MSIE 6.0;) JavaAjax/1.0";   
  45.   
  46.     // 默认的 编码    
  47.     public static final String DEFAULT_AJAX_CHARSET = "UTF-8";   
  48.     public static final String DEFAULT_HTTP_CHARSET = "ISO-8859-1";   
  49.        
  50.     // 默认的 HTTP method   
  51.     public static final String DEFAULT_REQUEST_METHOD = "POST";   
  52.   
  53.     private int readyState;   
  54.     private int status;   
  55.     private String statusText;   
  56.     private String responseHeaders;   
  57.     private byte[] responseBytes;   
  58.     private Map responseHeadersMap;   
  59.     private Map requestHeadersMap;   
  60.     private ReadyStateChangeListener readyStateChangeListener;   
  61.   
  62.     private boolean async;   
  63.     private boolean sent;   
  64.     private URLConnection connection;   
  65.     private String userAgent = DEFAULT_USERAGENT;   
  66.     private String postCharset = DEFAULT_AJAX_CHARSET;   
  67.     private Proxy proxy;   
  68.        
  69.     private URL requestURL;   
  70.     protected String requestMethod;   
  71.     protected String requestUserName;   
  72.     protected String requestPassword;   
  73.   
  74. /   
  75. /   
  76.   
  77.        
  78.     /**  
  79.      * 构造方法. 自动添加 XMLHttpRequest 的一些缺省头信息.  
  80.      * 如果不需要这些头信息,可在创建 AjaxHttpRequest 实例后,  
  81.      * 通过 setRequestHeader/removeRequestHeader/removeAllRequestHeaders 方法  
  82.      * 进行修改或移除.   
  83.      */  
  84.     public AjaxHttpRequest() {   
  85.         requestHeadersMap = new LinkedHashMap();   
  86.         setRequestHeader("X-Requested-With""XMLHttpRequest");   
  87.         setRequestHeader("Accept",   
  88.                 "text/javascript, text/html, application/xml, application/json, text/xml, */*");   
  89.     }   
  90.   
  91.     /**   
  92.      * 类似 XMLHttpRequest 中的 readyState 属性.   
  93.      */   
  94.     public synchronized int getReadyState() {   
  95.         return this.readyState;   
  96.     }   
  97.   
  98.     /**  
  99.      * 类似 XMLHttpRequest 中的 status 属性.  
  100.      */  
  101.     public synchronized int getStatus() {   
  102.         return this.status;   
  103.     }   
  104.   
  105.     /**  
  106.      * 类似 XMLHttpRequest 中的 statusText 属性.  
  107.      */  
  108.     public synchronized String getStatusText() {   
  109.         return this.statusText;   
  110.     }   
  111.        
  112.     /**  
  113.      * 类似 XMLHttpRequest 中的 setRequestHeader 方法.  
  114.      */  
  115.     public void setRequestHeader(String key, String value) {   
  116.         this.requestHeadersMap.put(key, value);   
  117.     }   
  118.        
  119.     /**  
  120.      * 类似 XMLHttpRequest 中的 open 方法.  
  121.      */  
  122.     public void open(String method, String url, boolean async, String userName, String password)   
  123.             throws IOException {   
  124.         URL urlObj = createURL(null, url);   
  125.         open(method, urlObj, async, userName, password);   
  126.     }   
  127.   
  128.        
  129.     /**  
  130.      * 类似 XMLHttpRequest 中的 open 方法.  
  131.      */  
  132.     public void open(final String method, final URL url, boolean async, final String userName,   
  133.             final String password) throws IOException {   
  134.         this.abort();   
  135.         Proxy proxy = this.proxy;   
  136.         URLConnection c = proxy == null || proxy == Proxy.NO_PROXY ? url.openConnection() : url   
  137.                 .openConnection(proxy);   
  138.         synchronized (this) {   
  139.             this.connection = c;   
  140.             this.async = async;   
  141.             this.requestMethod = method;   
  142.             this.requestURL = url;   
  143.             this.requestUserName = userName;   
  144.             this.requestPassword = password;   
  145.         }   
  146.         this.changeState(AjaxHttpRequest.STATE_LOADING, 0nullnull);   
  147.     }   
  148.   
  149.   
  150.     /**  
  151.      * 类似 XMLHttpRequest 中的 open 方法.  
  152.      * 省略部分参数的形式.  
  153.      */  
  154.     public void open(String url, boolean async) throws IOException {   
  155.         open(DEFAULT_REQUEST_METHOD, url, async, nullnull);   
  156.     }   
  157.        
  158.     /**  
  159.      * 类似 XMLHttpRequest 中的 open 方法.  
  160.      * 省略部分参数的形式.  
  161.      */  
  162.     public void open(String method, String url, boolean async) throws IOException {   
  163.         open(method, url, async, nullnull);   
  164.     }   
  165.        
  166.   
  167.     /**  
  168.      * 类似 XMLHttpRequest 中的 send 方法.  
  169.      * 支持发送 key-value 形式的数据集合(Map).  
  170.      * 传入map参数, 自动转换成string形式 并调用 send(String) 方法发送.  
  171.      */    
  172.     public void send(Map parameters) throws IOException {   
  173.         Iterator keyItr=parameters.keySet().iterator();   
  174.         StringBuffer strb=new StringBuffer();   
  175.         while (keyItr.hasNext()){   
  176.             Object key = keyItr.next();   
  177.             String keyStr = encode(key);   
  178.             String valueStr = encode(parameters.get(key));   
  179.             strb.append(keyStr).append("=").append(valueStr);   
  180.             strb.append("&");   
  181.         }   
  182.         send(strb.toString());   
  183.     }   
  184.        
  185.     /**  
  186.      * 类似 XMLHttpRequest 中的 send 方法.  
  187.      */  
  188.     public void send(final String content) throws IOException {   
  189.         final URL url = this.requestURL;   
  190.         if (url == null) {   
  191.             throw new IOException("No URL has been provided.");   
  192.         }   
  193.         if (this.isAsync()) {   
  194.             new Thread("AjaxHttpRequest-" + url.getHost()) {   
  195.                 public void run() {   
  196.                     try {   
  197.                         sendSync(content);   
  198.                     } catch (Throwable thrown) {   
  199.                         log(Level.WARNING, "send(): Error in asynchronous request on " + url, thrown);   
  200.                     }   
  201.                 }   
  202.             }.start();   
  203.         } else {   
  204.             sendSync(content);   
  205.         }   
  206.     }   
  207.        
  208.     /**  
  209.      * 类似 XMLHttpRequest 中的 getResponseHeader 方法.  
  210.      */  
  211.     public synchronized String getResponseHeader(String headerName) {   
  212.         return this.responseHeadersMap == null ? null : (String) this.responseHeadersMap.get(headerName);   
  213.     }   
  214.        
  215.     /**  
  216.      * 类似 XMLHttpRequest 中的 getAllResponseHeaders 方法.  
  217.      */  
  218.     public synchronized String getAllResponseHeaders() {   
  219.         return this.responseHeaders;   
  220.     }   
  221.        
  222.        
  223.     /**  
  224.      * 类似 XMLHttpRequest 中的 responseText 属性.  
  225.      */  
  226.     public synchronized String getResponseText() {   
  227.         byte[] bytes = this.responseBytes;   
  228.         String encoding = getCharset(this.connection);   
  229.         if (encoding==null){   
  230.             encoding=getPostCharset();   
  231.         }   
  232.         if (encoding == null) {   
  233.             encoding = DEFAULT_HTTP_CHARSET;   
  234.         }   
  235.         try {   
  236.             return bytes == null ? null : new String(bytes, encoding);   
  237.         } catch (UnsupportedEncodingException uee) {   
  238.             log(Level.WARNING, "getResponseText(): Charset '" + encoding + "' did not work. Retrying with "  
  239.                     + DEFAULT_HTTP_CHARSET + ".", uee);   
  240.             try {   
  241.                 return new String(bytes, DEFAULT_HTTP_CHARSET);   
  242.             } catch (UnsupportedEncodingException uee2) {   
  243.                 // Ignore this time   
  244.                 return null;   
  245.             }   
  246.         }   
  247.     }   
  248.   
  249.     /**  
  250.      * 类似 XMLHttpRequest 中的 responseXML 属性.  
  251.      * TODO : 此方法在java中 并不常使用, 而且需要两个额外的包,两个包不是所有的java环境都有的.  
  252.      *   所以我(fins)把此方法注释条了.   
  253.      *   如果确实需要此方法 请自行取消该方法的注释,并引入下面列出的类/接口.  
  254.      *     javax.xml.parsers.DocumentBuilderFactory;  
  255.      *     org.w3c.dom.Document;  
  256.      */  
  257. //        public synchronized Document getResponseXML() {    
  258. //            byte[] bytes =  this.responseBytes;    
  259. //            if (bytes == null) {    
  260. //                return null;    
  261. //            }    
  262. //            InputStream in =  new ByteArrayInputStream(bytes);    
  263. //            try {    
  264. //                return DocumentBuilderFactory.newInstance().newDocumentBuilder() .parse(in);    
  265. //            }catch (Exception err) {    
  266. //                log(Level.WARNING,  "Unable to parse response as XML.", err); return null;   
  267. //            }   
  268. //       }   
  269.        
  270.        
  271.     /**  
  272.      * 类似 XMLHttpRequest 中的 responseBody 属性.  
  273.      * @deprecated 这个方法命名源自XMLHttpRequest中的responseBody属性.  
  274.      * 不过这个名字并不是好名字.建议使用 getResponseBytes 方法代替之.  
  275.      */  
  276.     public synchronized byte[] getResponseBody() {   
  277.         return this.getResponseBytes();   
  278.     }   
  279.        
  280.     /**  
  281.      * 类似 XMLHttpRequest 中的 responseBody 属性.  
  282.      * 建议使用此方法代替 getResponseBody 方法.  
  283.      */  
  284.     public synchronized byte[] getResponseBytes() {   
  285.         return this.responseBytes;   
  286.     }      
  287.        
  288.     /**  
  289.      * 与 XMLHttpRequest 中的 responseStream 属性对应的方法 暂不提供.  
  290.      * 因为1 不常用 2 通常可用 getResponseBytes 方法代替   
  291.      */  
  292.        
  293.        
  294.     /**  
  295.      * 类似 XMLHttpRequest 中的 onreadystatechange 属性.  
  296.      * 设置一个监听器,用来跟踪HttpRequest状态变化.  
  297.      * 参数是一个 ReadyStateChangeListener 对象.  
  298.      * ReadyStateChangeListener 是一个抽象类. 只需 实现 onReadyStateChange方法即可.  
  299.      */  
  300.        
  301.     public void setReadyStateChangeListener(ReadyStateChangeListener listener) {   
  302.         this.readyStateChangeListener = listener;   
  303.     }   
  304.        
  305.     /**  
  306.      * 中断 Request 请求. 类似 XMLHttpRequest 中的 abort.  
  307.      */  
  308.     public void abort() {   
  309.         URLConnection c = null;   
  310.         synchronized (this) {   
  311.             c = this.getConnection();   
  312.         }   
  313.         if (c instanceof HttpURLConnection) {   
  314.             ((HttpURLConnection) c).disconnect();   
  315.         } else if (c != null) {   
  316.             try {   
  317.                 c.getInputStream().close();   
  318.             } catch (IOException ioe) {   
  319.                 ioe.printStackTrace();   
  320.             }   
  321.         }   
  322.     }   
  323.        
  324. ///   
  325.  以上 为 模拟 XMLHttpRequest 对象 相关的方法    
  326. ///   
  327. ///   
  328.        
  329.        
  330.     /**  
  331.      * 返回 此次HttpRequest是否是"异步"的.  
  332.      */  
  333.     public boolean isAsync() {   
  334.         return async;   
  335.     }   
  336.        
  337.     /**  
  338.      * 返回 此次HttpRequest是否已经发送.  
  339.      * 已经发送 且还没有完全处理完此次发送的返回信息时,是不能再次发送的.  
  340.      * 如果需要联系发送请求, 请再另行创建一个 AjaxHttpRequest对象.  
  341.      */  
  342.     public boolean hasSent() {   
  343.         return sent;   
  344.     }   
  345.     protected void setSent(boolean sent) {   
  346.         this.sent=sent;   
  347.     }   
  348.        
  349.     /**  
  350.      * 设置/取得 伪造的  userAgent 信息.通常不用理会.  
  351.      * 很少有http服务会对此做严格的判断.  
  352.      */  
  353.     public void setUserAgent(String userAgent) {   
  354.         this.userAgent = userAgent;   
  355.     }   
  356.     public String getUserAgent() {   
  357.         return this.userAgent;   
  358.     }   
  359.   
  360.     /**  
  361.      * 取得/设置 默认的 AJAX编码.AJAX请求都是UTF-8编码 此属性通常无需改变.  
  362.      */  
  363.     public String getPostCharset() {   
  364.         return this.postCharset;   
  365.     }   
  366.     public void setPostCharset(String postCharset) {   
  367.         this.postCharset = postCharset;   
  368.     }   
  369.        
  370.        
  371.     /**  
  372.      * 实现发送数据功能的方法,是整个类的核心.   
  373.      * 我(fins)借鉴了 cobra 组件的 org.lobobrowser.html.test.SimpleHttpRequest 类中的同名方法.  
  374.      * 略作改动.  
  375.      */  
  376.     protected void sendSync(String content) throws IOException {   
  377.         if (hasSent()){   
  378.             log(Level.WARNING, "This AjaxHttpRequest Object has sent"null);   
  379.             return ;   
  380.         }   
  381.         try {   
  382.             URLConnection c;   
  383.             synchronized (this) {   
  384.                 c = this.connection;   
  385.             }   
  386.             if (c==null){   
  387.                 log(Level.WARNING, "Please open AjaxHttpRequest first."null);   
  388.                 return ;   
  389.             }   
  390.             setSent(true);   
  391.             initConnectionRequestHeader(c);   
  392.             int istatus;   
  393.             String istatusText;   
  394.             InputStream err;   
  395.             if (c instanceof HttpURLConnection) {   
  396.                 HttpURLConnection hc = (HttpURLConnection) c;   
  397.                 String method = this.requestMethod==null?DEFAULT_REQUEST_METHOD:this.requestMethod;   
  398.        
  399.                 method = method.toUpperCase();   
  400.                 hc.setRequestMethod(method);   
  401.                 if ("POST".equals(method) && content != null) {   
  402.                     hc.setDoOutput(true);   
  403.                     byte[] contentBytes = content.getBytes(this.getPostCharset());   
  404.                     hc.setFixedLengthStreamingMode(contentBytes.length);   
  405.                     OutputStream out = hc.getOutputStream();   
  406.                     try {   
  407.                         out.write(contentBytes);   
  408.                     } finally {   
  409.                         out.flush();   
  410.                     }   
  411.                 }   
  412.                 istatus = hc.getResponseCode();   
  413.                 istatusText = hc.getResponseMessage();   
  414.                 err = hc.getErrorStream();   
  415.             } else {   
  416.                 istatus = 0;   
  417.                 istatusText = "";   
  418.                 err = null;   
  419.             }   
  420.             synchronized (this) {   
  421.                 this.responseHeaders = getConnectionResponseHeaders(c);   
  422.                 this.responseHeadersMap = c.getHeaderFields();   
  423.             }   
  424.             this.changeState(AjaxHttpRequest.STATE_LOADED, istatus, istatusText, null);   
  425.             InputStream in = err == null ? c.getInputStream() : err;   
  426.             int contentLength = c.getContentLength();   
  427.   
  428.             this.changeState(AjaxHttpRequest.STATE_INTERACTIVE, istatus, istatusText, null);   
  429.             byte[] bytes = loadStream(in, contentLength == -1 ? 4096 : contentLength);   
  430.             this.changeState(AjaxHttpRequest.STATE_COMPLETE, istatus, istatusText, bytes);   
  431.         } finally {   
  432.             synchronized (this) {   
  433.                 this.connection = null;   
  434.                 setSent(false);   
  435.             }   
  436.         }   
  437.     }   
  438.   
  439.        
  440.     /**  
  441.      * 当状态变化时 重新设置各种状态值,并触发状态变化监听器.  
  442.      */  
  443.     protected void changeState(int readyState, int status, String statusMessage, byte[] bytes) {   
  444.         synchronized (this) {   
  445.             this.readyState = readyState;   
  446.             this.status = status;   
  447.             this.statusText = statusMessage;   
  448.             this.responseBytes = bytes;   
  449.         }   
  450.         if (this.readyStateChangeListener!=null){   
  451.             this.readyStateChangeListener.onReadyStateChange();   
  452.         }   
  453.     }   
  454.   
  455.     /**  
  456.      * 对字符串进行 URLEncoder 编码.  
  457.      */  
  458.     protected String encode(Object str){   
  459.         try {   
  460.             return URLEncoder.encode(String.valueOf(str), getPostCharset());   
  461.         } catch (UnsupportedEncodingException e) {   
  462.             return String.valueOf(str);   
  463.         }   
  464.     }   
  465.        
  466.     /**  
  467.      * 将设置的 RequestHeader 真正的设置到链接请求中.  
  468.      */  
  469.     protected void initConnectionRequestHeader(URLConnection c) {   
  470.         c.setRequestProperty("User-Agent"this.getUserAgent());   
  471.         Iterator keyItor = this.requestHeadersMap.keySet().iterator();   
  472.         while (keyItor.hasNext()) {   
  473.             String key = (String) keyItor.next();   
  474.             String value = (String) this.requestHeadersMap.get(key);   
  475.             c.setRequestProperty(key, value);   
  476.         }   
  477.     }   
  478.   
  479.   
  480.     /**  
  481.      * 以下 4个 方法 负责处理 requestHeader信息.   
  482.      */  
  483.     public String getRequestHeader(String key) {   
  484.         return (String) this.requestHeadersMap.get(key);   
  485.     }   
  486.     public String removeRequestHeader(String key) {   
  487.         return (String)this.requestHeadersMap.remove(key);   
  488.     }   
  489.     public void removeAllRequestHeaders() {   
  490.         this.requestHeadersMap.clear();   
  491.     }   
  492.     public Map getAllRequestHeaders() {   
  493.         return this.requestHeadersMap;   
  494.     }   
  495.        
  496.        
  497.        
  498.     public URLConnection getConnection() {   
  499.         return connection;   
  500.     }   
  501.   
  502.     public void setConnection(URLConnection connection) {   
  503.         this.connection = connection;   
  504.     }   
  505.     public Proxy getProxy() {   
  506.         return proxy;   
  507.     }   
  508.     public void setProxy(Proxy proxy) {   
  509.         this.proxy = proxy;   
  510.     }   
  511.   
  512.        
  513.        
  514.     /   
  515.     // 以下是 Static Method //   
  516.     // 这些静态方法其实可以(应该)单独提取出去的, ///   
  517.     // 不过为了让这个程序结构简单些 , 我(fins)就全部 all in one 了.///   
  518.     // 这些方法也不都是我(fins)自己写的 很多是copy 借鉴来的 功能都挺简单的 就不详细说明了 //   
  519.     /   
  520.        
  521.     public static void log(Level level, String msg, Throwable thrown) {   
  522.         System.out.println(level.getName() + " : " + thrown.getMessage() + " ----- " + msg);   
  523.     }   
  524.     public static String getConnectionResponseHeaders(URLConnection c) {   
  525.         int idx = 0;   
  526.         String value;   
  527.         StringBuffer buf = new StringBuffer();   
  528.         while ((value = c.getHeaderField(idx)) != null) {   
  529.             String key = c.getHeaderFieldKey(idx);   
  530.             buf.append(key);   
  531.             buf.append(": ");   
  532.             buf.append(value);   
  533.             idx++;   
  534.         }   
  535.         return buf.toString();   
  536.     }   
  537.     public static String getCharset(URLConnection connection) {   
  538.         String contentType = connection==null?null:connection.getContentType();   
  539.         if (contentType != null) {   
  540.             StringTokenizer tok = new StringTokenizer(contentType, ";");   
  541.             if (tok.hasMoreTokens()) {   
  542.                 tok.nextToken();   
  543.                 while (tok.hasMoreTokens()) {   
  544.                     String assignment = tok.nextToken().trim();   
  545.                     int eqIdx = assignment.indexOf('=');   
  546.                     if (eqIdx != -1) {   
  547.                         String varName = assignment.substring(0, eqIdx).trim();   
  548.                         if ("charset".equalsIgnoreCase(varName)) {   
  549.                             String varValue = assignment.substring(eqIdx + 1);   
  550.                             return unquote(varValue.trim());   
  551.                         }   
  552.                     }   
  553.                 }   
  554.             }   
  555.         }   
  556.         return null;   
  557.     }   
  558.     public static String unquote(String text) {   
  559.         if (text.startsWith("/"") && text.endsWith("/"")) {   
  560.             return text.substring(1, text.length() - 2);   
  561.         }   
  562.         return text;   
  563.     }   
  564.     protected static URL createURL(URL baseUrl, String relativeUrl) throws MalformedURLException {   
  565.         return new URL(baseUrl, relativeUrl);   
  566.     }   
  567.     protected static byte[] loadStream(InputStream in, int initialBufferSize) throws IOException {   
  568.         if (initialBufferSize == 0) {   
  569.             initialBufferSize = 1;   
  570.         }   
  571.         byte[] buffer = new byte[initialBufferSize];   
  572.         int offset = 0;   
  573.         for (;;) {   
  574.             int remain = buffer.length - offset;   
  575.             if (remain <= 0) {   
  576.                 int newSize = buffer.length * 2;   
  577.                 byte[] newBuffer = new byte[newSize];   
  578.                 System.arraycopy(buffer, 0, newBuffer, 0, offset);   
  579.                 buffer = newBuffer;   
  580.                 remain = buffer.length - offset;   
  581.             }   
  582.             int numRead = in.read(buffer, offset, remain);   
  583.             if (numRead == -1) {   
  584.                 break;   
  585.             }   
  586.             offset += numRead;   
  587.         }   
  588.         if (offset < buffer.length) {   
  589.             byte[] newBuffer = new byte[offset];   
  590.             System.arraycopy(buffer, 0, newBuffer, 0, offset);   
  591.             buffer = newBuffer;   
  592.         }   
  593.         return buffer;   
  594.     }   
  595.   
  596.   
  597.     ///    
  598.     // Listener Class /   
  599.     ///   
  600.        
  601.     /**  
  602.      * 一个用来监听 HttpRequest状态 的监听器. 是一个内部静态抽象类.  
  603.      * 可以根据实际情况来自行重构(如 增加方法、变为独立的外部类等).  
  604.      */  
  605.     public static abstract class ReadyStateChangeListener {   
  606.         public abstract void onReadyStateChange();   
  607.     }   
  608.        
  609.   
  610.   
  611.     ///    
  612.     // Test Method    
  613.     ///   
  614.        
  615.     /**  
  616.      * 利用这个AjaxHttpReuqest类来实现 对google translate服务的访问 .  
  617.      * 只演示了 "英-->汉"的翻译.  
  618.      * 返回的是JSON字符串,需要使用Json工具类进行转换,这个不难 就不详细举例了.  
  619.      */  
  620.     public static void testGoogleTranslate(String words,boolean async) throws IOException {   
  621.         Map params=new HashMap();   
  622.         params.put("q",words);   
  623.         params.put("v","1.0");   
  624.         params.put("langpair","en|zh-CN");   
  625.         String url="http://ajax.googleapis.com/ajax/services/language/translate";   
  626.            
  627.         // 以上为 调用google翻译服务所需要的参数.   
  628.         // 下面 是用java 来调用这个 翻译服务.   
  629.         // 在 AjaxHttpRequest 类的 帮助下 我们可以使用 类似操作浏览器XHR对象的方式来 实现该功能.   
  630.        
  631.            
  632.         // 创建 AjaxHttpRequest对象 相当于 创建 XHR对象.   
  633.         // 这里的final 主要是为了"使监听器内部能够调用ajax对象"而加的.   
  634.         final AjaxHttpRequest ajax=new AjaxHttpRequest();   
  635.            
  636.         // 设置状态监听器,类似 XHR对象的 onreadystatechange 属性.   
  637.         // 由于js 和java的本质区别 导致这里可能和 xhr有点不一样,但是应该不难理解.   
  638.         ajax.setReadyStateChangeListener(   
  639.                 // 监听器, 根据需求 实现onReadyStateChange方法即可.   
  640.                 new AjaxHttpRequest.ReadyStateChangeListener(){   
  641.                         public void onReadyStateChange() {   
  642.                             int readyState = ajax.getReadyState();   
  643.                             //判断状态 然后做出相应处理.   
  644.                             if (readyState==AjaxHttpRequest.STATE_COMPLETE){   
  645.                                 System.out.println( ajax.getResponseText() );   
  646.                             }   
  647.                         }              
  648.                 }   
  649.         );   
  650.            
  651.         // 这里就和 xhr 几乎完全一样了   
  652.         ajax.open("POST", url, true);   
  653.            
  654.         //这里这个send方法接受的参数是一个map ,当然AjaxHttpRequest类也提供了string的方法   
  655.         ajax.send(params);   
  656.   
  657.     }   
  658.        
  659.     public static void main(String[] args) throws IOException {   
  660.                
  661.         testGoogleTranslate("Hello world!",false);   
  662.            
  663.     }   
  664.        
  665.   
  666. }  

 

转自: javaeye

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值