空間站

          北極心空

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks
          http://fins.javaeye.com/blog/261525?page=1#comments

          這里所說的"模擬" 是指 : 在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 類) :

          /**  
           * 利用這個AjaxHttpReuqest類來實現 對google translate服務的訪問 .  
           * 只演示了 "英-->漢"的翻譯.  
           * 返回的是JSON字符串,需要使用Json工具類進行轉換,這個不難 就不詳細舉例了.  
           
          */  
          public static void testGoogleTranslate(String words,boolean async) throws IOException {   
              Map params
          =new HashMap();   
              params.put(
          "q",words);   
              params.put(
          "v","1.0");   
              params.put(
          "langpair","en|zh-CN");   
              String url
          ="http://ajax.googleapis.com/ajax/services/language/translate";   
                 
              
          // 以上為 調用google翻譯服務所需要的參數.   
              
          // 下面 是用java 來調用這個 翻譯服務.   
              
          // 在 AjaxHttpRequest 類的 幫助下 我們可以使用 類似操作瀏覽器XHR對象的方式來 實現該功能.   
            
                 
              
          // 創建 AjaxHttpRequest對象 相當于 創建 XHR對象.   
              
          // 這里的final 主要是為了"使監聽器內部能夠調用ajax對象"而加的.   
              final AjaxHttpRequest ajax=new AjaxHttpRequest();   
                 
              
          // 設置狀態監聽器,類似 XHR對象的 onreadystatechange 屬性.   
              
          // 由于js 和java的本質區別 導致這里可能和 xhr有點不一樣,但是應該不難理解.   
              ajax.setReadyStateChangeListener(   
                      
          // 監聽器, 根據需求 實現onReadyStateChange方法即可.   
                      new AjaxHttpRequest.ReadyStateChangeListener(){   
                              
          public void onReadyStateChange() {   
                                  
          int readyState = ajax.getReadyState();   
                                  
          //判斷狀態 然后做出相應處理.   
                                  if (readyState==AjaxHttpRequest.STATE_COMPLETE){   
                                      System.out.println( ajax.getResponseText() );   
                                  }   
                              }              
                      }   
              );   
                 
              
          // 這里就和 xhr 幾乎完全一樣了   
              ajax.open("POST", url, true);   
                 
              
          //這里這個send方法接受的參數是一個map ,當然AjaxHttpRequest類也提供了string的方法   
              ajax.send(params);   
            
          }  

          有了上面的功能 當頁面中要使用google的翻譯服務時 就不用在引入google的那些js了.
          也不用擔心 客戶端無法訪問google的情況了.



          下面附上 AjaxHttpRequest類 的完整代碼 ( 附件中有下載 )
          package com.fins.gt.server;   
            
          import java.io.IOException;   
          import java.io.InputStream;   
          import java.io.OutputStream;   
          import java.io.UnsupportedEncodingException;   
          import java.net.HttpURLConnection;   
          import java.net.MalformedURLException;   
          import java.net.Proxy;   
          import java.net.URL;   
          import java.net.URLConnection;   
          import java.net.URLEncoder;   
          import java.util.HashMap;   
          import java.util.Iterator;   
          import java.util.LinkedHashMap;   
          import java.util.Map;   
          import java.util.StringTokenizer;   
          import java.util.logging.Level;   
            
                     
          /**  
           * AjaxHttpRequest ,用java 模擬 瀏覽器的 XMLHttpRequest 對象.  
           * 目的是 用 操作瀏覽器中的XHR對象的 方式來處理java端的 http請求.  
           *   
           * 
          @author fins  
           *   
           * 本類的實現借鑒了 cobra 組件的 org.lobobrowser.html.test.SimpleHttpRequest 類.  
           * 可以看作是對 SimpleHttpRequest 類的一個完善和補充.  
           *   
           * cobra 組件是一個 Java HTML Renderer & Parser,  
           * 官方網站 : 
          http://lobobrowser.org/cobra.jsp  
           
          */  
            
          public class AjaxHttpRequest {   
            
              
          // 對應 XMLHttpRequest 的5種狀態.   
              public static final int STATE_UNINITIALIZED = 0;   
              
          public static final int STATE_LOADING = 1;   
              
          public static final int STATE_LOADED = 2;   
              
          public static final int STATE_INTERACTIVE = 3;   
              
          public static final int STATE_COMPLETE = 4;   
            
              
          // 默認的 userAgent    
              public static final String DEFAULT_USERAGENT = "Mozilla/4.0 (compatible; MSIE 6.0;) JavaAjax/1.0";   
            
              
          // 默認的 編碼    
              public static final String DEFAULT_AJAX_CHARSET = "UTF-8";   
              
          public static final String DEFAULT_HTTP_CHARSET = "ISO-8859-1";   
                 
              
          // 默認的 HTTP method   
              public static final String DEFAULT_REQUEST_METHOD = "POST";   
            
              
          private int readyState;   
              
          private int status;   
              
          private String statusText;   
              
          private String responseHeaders;   
              
          private byte[] responseBytes;   
              
          private Map responseHeadersMap;   
              
          private Map requestHeadersMap;   
              
          private ReadyStateChangeListener readyStateChangeListener;   
            
              
          private boolean async;   
              
          private boolean sent;   
              
          private URLConnection connection;   
              
          private String userAgent = DEFAULT_USERAGENT;   
              
          private String postCharset = DEFAULT_AJAX_CHARSET;   
              
          private Proxy proxy;   
                 
              
          private URL requestURL;   
              
          protected String requestMethod;   
              
          protected String requestUserName;   
              
          protected String requestPassword;   
            
          /////////////////////////////////   
          ////////////////////////////////
          /   
            
                 
              
          /**  
               * 構造方法. 自動添加 XMLHttpRequest 的一些缺省頭信息.  
               * 如果不需要這些頭信息,可在創建 AjaxHttpRequest 實例后,  
               * 通過 setRequestHeader/removeRequestHeader/removeAllRequestHeaders 方法  
               * 進行修改或移除.   
               
          */  
              
          public AjaxHttpRequest() {   
                  requestHeadersMap 
          = new LinkedHashMap();   
                  setRequestHeader(
          "X-Requested-With""XMLHttpRequest");   
                  setRequestHeader(
          "Accept",   
                          
          "text/javascript, text/html, application/xml, application/json, text/xml, */*");   
              }   
            
              
          /**   
               * 類似 XMLHttpRequest 中的 readyState 屬性.   
               
          */   
              
          public synchronized int getReadyState() {   
                  
          return this.readyState;   
              }   
            
              
          /**  
               * 類似 XMLHttpRequest 中的 status 屬性.  
               
          */  
              
          public synchronized int getStatus() {   
                  
          return this.status;   
              }   
            
              
          /**  
               * 類似 XMLHttpRequest 中的 statusText 屬性.  
               
          */  
              
          public synchronized String getStatusText() {   
                  
          return this.statusText;   
              }   
                 
              
          /**  
               * 類似 XMLHttpRequest 中的 setRequestHeader 方法.  
               
          */  
              
          public void setRequestHeader(String key, String value) {   
                  
          this.requestHeadersMap.put(key, value);   
              }   
                 
              
          /**  
               * 類似 XMLHttpRequest 中的 open 方法.  
               
          */  
              
          public void open(String method, String url, boolean async, String userName, String password)   
                      
          throws IOException {   
                  URL urlObj 
          = createURL(null, url);   
                  open(method, urlObj, async, userName, password);   
              }   
            
                 
              
          /**  
               * 類似 XMLHttpRequest 中的 open 方法.  
               
          */  
              
          public void open(final String method, final URL url, boolean async, final String userName,   
                      
          final String password) throws IOException {   
                  
          this.abort();   
                  Proxy proxy 
          = this.proxy;   
                  URLConnection c 
          = proxy == null || proxy == Proxy.NO_PROXY ? url.openConnection() : url   
                          .openConnection(proxy);   
                  
          synchronized (this) {   
                      
          this.connection = c;   
                      
          this.async = async;   
                      
          this.requestMethod = method;   
                      
          this.requestURL = url;   
                      
          this.requestUserName = userName;   
                      
          this.requestPassword = password;   
                  }   
                  
          this.changeState(AjaxHttpRequest.STATE_LOADING, 0nullnull);   
              }   
            
            
              
          /**  
               * 類似 XMLHttpRequest 中的 open 方法.  
               * 省略部分參數的形式.  
               
          */  
              
          public void open(String url, boolean async) throws IOException {   
                  open(DEFAULT_REQUEST_METHOD, url, async, 
          nullnull);   
              }   
                 
              
          /**  
               * 類似 XMLHttpRequest 中的 open 方法.  
               * 省略部分參數的形式.  
               
          */  
              
          public void open(String method, String url, boolean async) throws IOException {   
                  open(method, url, async, 
          nullnull);   
              }   
                 
            
              
          /**  
               * 類似 XMLHttpRequest 中的 send 方法.  
               * 支持發送 key-value 形式的數據集合(Map).  
               * 傳入map參數, 自動轉換成string形式 并調用 send(String) 方法發送.  
               
          */    
              
          public void send(Map parameters) throws IOException {   
                  Iterator keyItr
          =parameters.keySet().iterator();   
                  StringBuffer strb
          =new StringBuffer();   
                  
          while (keyItr.hasNext()){   
                      Object key 
          = keyItr.next();   
                      String keyStr 
          = encode(key);   
                      String valueStr 
          = encode(parameters.get(key));   
                      strb.append(keyStr).append(
          "=").append(valueStr);   
                      strb.append(
          "&");   
                  }   
                  send(strb.toString());   
              }   
                 
              
          /**  
               * 類似 XMLHttpRequest 中的 send 方法.  
               
          */  
              
          public void send(final String content) throws IOException {   
                  
          final URL url = this.requestURL;   
                  
          if (url == null) {   
                      
          throw new IOException("No URL has been provided.");   
                  }   
                  
          if (this.isAsync()) {   
                      
          new Thread("AjaxHttpRequest-" + url.getHost()) {   
                          
          public void run() {   
                              
          try {   
                                  sendSync(content);   
                              } 
          catch (Throwable thrown) {   
                                  log(Level.WARNING, 
          "send(): Error in asynchronous request on " + url, thrown);   
                              }   
                          }   
                      }.start();   
                  } 
          else {   
                      sendSync(content);   
                  }   
              }   
                 
              
          /**  
               * 類似 XMLHttpRequest 中的 getResponseHeader 方法.  
               
          */  
              
          public synchronized String getResponseHeader(String headerName) {   
                  
          return this.responseHeadersMap == null ? null : (String) this.responseHeadersMap.get(headerName);   
              }   
                 
              
          /**  
               * 類似 XMLHttpRequest 中的 getAllResponseHeaders 方法.  
               
          */  
              
          public synchronized String getAllResponseHeaders() {   
                  
          return this.responseHeaders;   
              }   
                 
                 
              
          /**  
               * 類似 XMLHttpRequest 中的 responseText 屬性.  
               
          */  
              
          public synchronized String getResponseText() {   
                  
          byte[] bytes = this.responseBytes;   
                  String encoding 
          = getCharset(this.connection);   
                  
          if (encoding==null){   
                      encoding
          =getPostCharset();   
                  }   
                  
          if (encoding == null) {   
                      encoding 
          = DEFAULT_HTTP_CHARSET;   
                  }   
                  
          try {   
                      
          return bytes == null ? null : new String(bytes, encoding);   
                  } 
          catch (UnsupportedEncodingException uee) {   
                      log(Level.WARNING, 
          "getResponseText(): Charset '" + encoding + "' did not work. Retrying with "  
                              
          + DEFAULT_HTTP_CHARSET + ".", uee);   
                      
          try {   
                          
          return new String(bytes, DEFAULT_HTTP_CHARSET);   
                      } 
          catch (UnsupportedEncodingException uee2) {   
                          
          // Ignore this time   
                          return null;   
                      }   
                  }   
              }   
            
              
          /**  
               * 類似 XMLHttpRequest 中的 responseXML 屬性.  
               * TODO : 此方法在java中 并不常使用, 而且需要兩個額外的包,兩個包不是所有的java環境都有的.  
               *   所以我(fins)把此方法注釋條了.   
               *   如果確實需要此方法 請自行取消該方法的注釋,并引入下面列出的類/接口.  
               *     javax.xml.parsers.DocumentBuilderFactory;  
               *     org.w3c.dom.Document;  
               
          */  
          //        public synchronized Document getResponseXML() {    
          //            byte[] bytes =  this.responseBytes;    
          //            if (bytes == null) {    
          //                return null;    
          //            }    
          //            InputStream in =  new ByteArrayInputStream(bytes);    
          //            try {    
          //                return DocumentBuilderFactory.newInstance().newDocumentBuilder() .parse(in);    
          //            }catch (Exception err) {    
          //                log(Level.WARNING,  "Unable to parse response as XML.", err); return null;   
          //            }   
          //       }   
                 
                 
              
          /**  
               * 類似 XMLHttpRequest 中的 responseBody 屬性.  
               * 
          @deprecated 這個方法命名源自XMLHttpRequest中的responseBody屬性.  
               * 不過這個名字并不是好名字.建議使用 getResponseBytes 方法代替之.  
               
          */  
              
          public synchronized byte[] getResponseBody() {   
                  
          return this.getResponseBytes();   
              }   
                 
              
          /**  
               * 類似 XMLHttpRequest 中的 responseBody 屬性.  
               * 建議使用此方法代替 getResponseBody 方法.  
               
          */  
              
          public synchronized byte[] getResponseBytes() {   
                  
          return this.responseBytes;   
              }      
                 
              
          /**  
               * 與 XMLHttpRequest 中的 responseStream 屬性對應的方法 暫不提供.  
               * 因為1 不常用 2 通常可用 getResponseBytes 方法代替   
               
          */  
                 
                 
              
          /**  
               * 類似 XMLHttpRequest 中的 onreadystatechange 屬性.  
               * 設置一個監聽器,用來跟蹤HttpRequest狀態變化.  
               * 參數是一個 ReadyStateChangeListener 對象.  
               * ReadyStateChangeListener 是一個抽象類. 只需 實現 onReadyStateChange方法即可.  
               
          */  
                 
              
          public void setReadyStateChangeListener(ReadyStateChangeListener listener) {   
                  
          this.readyStateChangeListener = listener;   
              }   
                 
              
          /**  
               * 中斷 Request 請求. 類似 XMLHttpRequest 中的 abort.  
               
          */  
              
          public void abort() {   
                  URLConnection c 
          = null;   
                  
          synchronized (this) {   
                      c 
          = this.getConnection();   
                  }   
                  
          if (c instanceof HttpURLConnection) {   
                      ((HttpURLConnection) c).disconnect();   
                  } 
          else if (c != null) {   
                      
          try {   
                          c.getInputStream().close();   
                      } 
          catch (IOException ioe) {   
                          ioe.printStackTrace();   
                      }   
                  }   
              }   
                 
          ///////////////////////////////////////////////   
          ////
           以上 為 模擬 XMLHttpRequest 對象 相關的方法 ////   
          //////////////////////////////////////////////
          /   
          //////////////////////////////////////////////
          /   
                 
                 
              
          /**  
               * 返回 此次HttpRequest是否是"異步"的.  
               
          */  
              
          public boolean isAsync() {   
                  
          return async;   
              }   
                 
              
          /**  
               * 返回 此次HttpRequest是否已經發送.  
               * 已經發送 且還沒有完全處理完此次發送的返回信息時,是不能再次發送的.  
               * 如果需要聯系發送請求, 請再另行創建一個 AjaxHttpRequest對象.  
               
          */  
              
          public boolean hasSent() {   
                  
          return sent;   
              }   
              
          protected void setSent(boolean sent) {   
                  
          this.sent=sent;   
              }   
                 
              
          /**  
               * 設置/取得 偽造的  userAgent 信息.通常不用理會.  
               * 很少有http服務會對此做嚴格的判斷.  
               
          */  
              
          public void setUserAgent(String userAgent) {   
                  
          this.userAgent = userAgent;   
              }   
              
          public String getUserAgent() {   
                  
          return this.userAgent;   
              }   
            
              
          /**  
               * 取得/設置 默認的 AJAX編碼.AJAX請求都是UTF-8編碼 此屬性通常無需改變.  
               
          */  
              
          public String getPostCharset() {   
                  
          return this.postCharset;   
              }   
              
          public void setPostCharset(String postCharset) {   
                  
          this.postCharset = postCharset;   
              }   
                 
                 
              
          /**  
               * 實現發送數據功能的方法,是整個類的核心.   
               * 我(fins)借鑒了 cobra 組件的 org.lobobrowser.html.test.SimpleHttpRequest 類中的同名方法.  
               * 略作改動.  
               
          */  
              
          protected void sendSync(String content) throws IOException {   
                  
          if (hasSent()){   
                      log(Level.WARNING, 
          "This AjaxHttpRequest Object has sent"null);   
                      
          return ;   
                  }   
                  
          try {   
                      URLConnection c;   
                      
          synchronized (this) {   
                          c 
          = this.connection;   
                      }   
                      
          if (c==null){   
                          log(Level.WARNING, 
          "Please open AjaxHttpRequest first."null);   
                          
          return ;   
                      }   
                      setSent(
          true);   
                      initConnectionRequestHeader(c);   
                      
          int istatus;   
                      String istatusText;   
                      InputStream err;   
                      
          if (c instanceof HttpURLConnection) {   
                          HttpURLConnection hc 
          = (HttpURLConnection) c;   
                          String method 
          = this.requestMethod==null?DEFAULT_REQUEST_METHOD:this.requestMethod;   
                 
                          method 
          = method.toUpperCase();   
                          hc.setRequestMethod(method);   
                          
          if ("POST".equals(method) && content != null) {   
                              hc.setDoOutput(
          true);   
                              
          byte[] contentBytes = content.getBytes(this.getPostCharset());   
                              hc.setFixedLengthStreamingMode(contentBytes.length);   
                              OutputStream out 
          = hc.getOutputStream();   
                              
          try {   
                                  out.write(contentBytes);   
                              } 
          finally {   
                                  out.flush();   
                              }   
                          }   
                          istatus 
          = hc.getResponseCode();   
                          istatusText 
          = hc.getResponseMessage();   
                          err 
          = hc.getErrorStream();   
                      } 
          else {   
                          istatus 
          = 0;   
                          istatusText 
          = "";   
                          err 
          = null;   
                      }   
                      
          synchronized (this) {   
                          
          this.responseHeaders = getConnectionResponseHeaders(c);   
                          
          this.responseHeadersMap = c.getHeaderFields();   
                      }   
                      
          this.changeState(AjaxHttpRequest.STATE_LOADED, istatus, istatusText, null);   
                      InputStream in 
          = err == null ? c.getInputStream() : err;   
                      
          int contentLength = c.getContentLength();   
            
                      
          this.changeState(AjaxHttpRequest.STATE_INTERACTIVE, istatus, istatusText, null);   
                      
          byte[] bytes = loadStream(in, contentLength == -1 ? 4096 : contentLength);   
                      
          this.changeState(AjaxHttpRequest.STATE_COMPLETE, istatus, istatusText, bytes);   
                  } 
          finally {   
                      
          synchronized (this) {   
                          
          this.connection = null;   
                          setSent(
          false);   
                      }   
                  }   
              }   
            
                 
              
          /**  
               * 當狀態變化時 重新設置各種狀態值,并觸發狀態變化監聽器.  
               
          */  
              
          protected void changeState(int readyState, int status, String statusMessage, byte[] bytes) {   
                  
          synchronized (this) {   
                      
          this.readyState = readyState;   
                      
          this.status = status;   
                      
          this.statusText = statusMessage;   
                      
          this.responseBytes = bytes;   
                  }   
                  
          if (this.readyStateChangeListener!=null){   
                      
          this.readyStateChangeListener.onReadyStateChange();   
                  }   
              }   
            
              
          /**  
               * 對字符串進行 URLEncoder 編碼.  
               
          */  
              
          protected String encode(Object str){   
                  
          try {   
                      
          return URLEncoder.encode(String.valueOf(str), getPostCharset());   
                  } 
          catch (UnsupportedEncodingException e) {   
                      
          return String.valueOf(str);   
                  }   
              }   
                 
              
          /**  
               * 將設置的 RequestHeader 真正的設置到鏈接請求中.  
               
          */  
              
          protected void initConnectionRequestHeader(URLConnection c) {   
                  c.setRequestProperty(
          "User-Agent"this.getUserAgent());   
                  Iterator keyItor 
          = this.requestHeadersMap.keySet().iterator();   
                  
          while (keyItor.hasNext()) {   
                      String key 
          = (String) keyItor.next();   
                      String value 
          = (String) this.requestHeadersMap.get(key);   
                      c.setRequestProperty(key, value);   
                  }   
              }   
            
            
              
          /**  
               * 以下 4個 方法 負責處理 requestHeader信息.   
               
          */  
              
          public String getRequestHeader(String key) {   
                  
          return (String) this.requestHeadersMap.get(key);   
              }   
              
          public String removeRequestHeader(String key) {   
                  
          return (String)this.requestHeadersMap.remove(key);   
              }   
              
          public void removeAllRequestHeaders() {   
                  
          this.requestHeadersMap.clear();   
              }   
              
          public Map getAllRequestHeaders() {   
                  
          return this.requestHeadersMap;   
              }   
                 
                 
                 
              
          public URLConnection getConnection() {   
                  
          return connection;   
              }   
            
              
          public void setConnection(URLConnection connection) {   
                  
          this.connection = connection;   
              }   
              
          public Proxy getProxy() {   
                  
          return proxy;   
              }   
              
          public void setProxy(Proxy proxy) {   
                  
          this.proxy = proxy;   
              }   
            
                 
                 
              
          /////////////////////////////////////////////////////////////////////   
              
          // 以下是 Static Method //////////////////////////////////////////////   
              
          // 這些靜態方法其實可以(應該)單獨提取出去的, ///////////////////////////////   
              
          // 不過為了讓這個程序結構簡單些 , 我(fins)就全部 all in one 了.///////////////////   
              
          // 這些方法也不都是我(fins)自己寫的 很多是copy 借鑒來的 功能都挺簡單的 就不詳細說明了 //   
              /////////////////////////////////////////////////////////////////////   
                 
              
          public static void log(Level level, String msg, Throwable thrown) {   
                  System.out.println(level.getName() 
          + " : " + thrown.getMessage() + " ----- " + msg);   
              }   
              
          public static String getConnectionResponseHeaders(URLConnection c) {   
                  
          int idx = 0;   
                  String value;   
                  StringBuffer buf 
          = new StringBuffer();   
                  
          while ((value = c.getHeaderField(idx)) != null) {   
                      String key 
          = c.getHeaderFieldKey(idx);   
                      buf.append(key);   
                      buf.append(
          "");   
                      buf.append(value);   
                      idx
          ++;   
                  }   
                  
          return buf.toString();   
              }   
              
          public static String getCharset(URLConnection connection) {   
                  String contentType 
          = connection==null?null:connection.getContentType();   
                  
          if (contentType != null) {   
                      StringTokenizer tok 
          = new StringTokenizer(contentType, ";");   
                      
          if (tok.hasMoreTokens()) {   
                          tok.nextToken();   
                          
          while (tok.hasMoreTokens()) {   
                              String assignment 
          = tok.nextToken().trim();   
                              
          int eqIdx = assignment.indexOf('=');   
                              
          if (eqIdx != -1) {   
                                  String varName 
          = assignment.substring(0, eqIdx).trim();   
                                  
          if ("charset".equalsIgnoreCase(varName)) {   
                                      String varValue 
          = assignment.substring(eqIdx + 1);   
                                      
          return unquote(varValue.trim());   
                                  }   
                              }   
                          }   
                      }   
                  }   
                  
          return null;   
              }   
              
          public static String unquote(String text) {   
                  
          if (text.startsWith("\"") && text.endsWith("\"")) {   
                      
          return text.substring(1, text.length() - 2);   
                  }   
                  
          return text;   
              }   
              
          protected static URL createURL(URL baseUrl, String relativeUrl) throws MalformedURLException {   
                  
          return new URL(baseUrl, relativeUrl);   
              }   
              
          protected static byte[] loadStream(InputStream in, int initialBufferSize) throws IOException {   
                  
          if (initialBufferSize == 0) {   
                      initialBufferSize 
          = 1;   
                  }   
                  
          byte[] buffer = new byte[initialBufferSize];   
                  
          int offset = 0;   
                  
          for (;;) {   
                      
          int remain = buffer.length - offset;   
                      
          if (remain <= 0) {   
                          
          int newSize = buffer.length * 2;   
                          
          byte[] newBuffer = new byte[newSize];   
                          System.arraycopy(buffer, 
          0, newBuffer, 0, offset);   
                          buffer 
          = newBuffer;   
                          remain 
          = buffer.length - offset;   
                      }   
                      
          int numRead = in.read(buffer, offset, remain);   
                      
          if (numRead == -1) {   
                          
          break;   
                      }   
                      offset 
          += numRead;   
                  }   
                  
          if (offset < buffer.length) {   
                      
          byte[] newBuffer = new byte[offset];   
                      System.arraycopy(buffer, 
          0, newBuffer, 0, offset);   
                      buffer 
          = newBuffer;   
                  }   
                  
          return buffer;   
              }   
            
            
              
          ///////////////////////////////////////////////////////////    
              
          // Listener Class /////////////////////////////////////////   
              ///////////////////////////////////////////////////////////   
                 
              
          /**  
               * 一個用來監聽 HttpRequest狀態 的監聽器. 是一個內部靜態抽象類.  
               * 可以根據實際情況來自行重構(如 增加方法、變為獨立的外部類等).  
               
          */  
              
          public static abstract class ReadyStateChangeListener {   
                  
          public abstract void onReadyStateChange();   
              }   
                 
            
            
              
          ///////////////////////////////////////////////////////////    
              
          // Test Method ////////////////////////////////////////////   
              ///////////////////////////////////////////////////////////   
                 
              
          /**  
               * 利用這個AjaxHttpReuqest類來實現 對google translate服務的訪問 .  
               * 只演示了 "英-->漢"的翻譯.  
               * 返回的是JSON字符串,需要使用Json工具類進行轉換,這個不難 就不詳細舉例了.  
               
          */  
              
          public static void testGoogleTranslate(String words,boolean async) throws IOException {   
                  Map params
          =new HashMap();   
                  params.put(
          "q",words);   
                  params.put(
          "v","1.0");   
                  params.put(
          "langpair","en|zh-CN");   
                  String url
          ="http://ajax.googleapis.com/ajax/services/language/translate";   
                     
                  
          // 以上為 調用google翻譯服務所需要的參數.   
                  
          // 下面 是用java 來調用這個 翻譯服務.   
                  
          // 在 AjaxHttpRequest 類的 幫助下 我們可以使用 類似操作瀏覽器XHR對象的方式來 實現該功能.   
                 
                     
                  
          // 創建 AjaxHttpRequest對象 相當于 創建 XHR對象.   
                  
          // 這里的final 主要是為了"使監聽器內部能夠調用ajax對象"而加的.   
                  final AjaxHttpRequest ajax=new AjaxHttpRequest();   
                     
                  
          // 設置狀態監聽器,類似 XHR對象的 onreadystatechange 屬性.   
                  
          // 由于js 和java的本質區別 導致這里可能和 xhr有點不一樣,但是應該不難理解.   
                  ajax.setReadyStateChangeListener(   
                          
          // 監聽器, 根據需求 實現onReadyStateChange方法即可.   
                          new AjaxHttpRequest.ReadyStateChangeListener(){   
                                  
          public void onReadyStateChange() {   
                                      
          int readyState = ajax.getReadyState();   
                                      
          //判斷狀態 然后做出相應處理.   
                                      if (readyState==AjaxHttpRequest.STATE_COMPLETE){   
                                          System.out.println( ajax.getResponseText() );   
                                      }   
                                  }              
                          }   
                  );   
                     
                  
          // 這里就和 xhr 幾乎完全一樣了   
                  ajax.open("POST", url, true);   
                     
                  
          //這里這個send方法接受的參數是一個map ,當然AjaxHttpRequest類也提供了string的方法   
                  ajax.send(params);   
            
              }   
                 
              
          public static void main(String[] args) throws IOException {   
                         
                  testGoogleTranslate(
          "Hello world!",false);   
                     
              }   
                 
            
          }  

        1. AjaxHttpRequest.zip (6.5 KB)
        2. 描述: AjaxHttpRequest類 的完整代碼
        3. 下載次數: 281
        4. posted on 2008-11-26 12:44 蘆葦 閱讀(2557) 評論(0)  編輯  收藏 所屬分類: JAVA其他
          主站蜘蛛池模板: 伊金霍洛旗| 绥德县| 班戈县| 阳泉市| 红桥区| 江川县| 安吉县| 巩留县| 沈丘县| 泽普县| 庆阳市| 徐汇区| 丰镇市| 平乡县| 余干县| 宁安市| 佳木斯市| 监利县| 汕头市| 黎川县| 新乐市| 应用必备| 崇文区| 八宿县| 平乐县| 新巴尔虎右旗| 玉林市| 门头沟区| 綦江县| 尉犁县| 武平县| 广河县| 五大连池市| 广宗县| 东丰县| 湛江市| 思南县| 尖扎县| 油尖旺区| 博野县| 荃湾区|