2011-02-08 61 views
2

我正在寫一個Java代理中的小代理,它基本上挑選出2個特定文件並對它們進行一些額外的處理。一個URL只是在傳遞內容之前從內容中獲取一些信息。另一個文件我想過濾響應內容,這只是xml deflate編碼(我想刪除一些子元素)。Java Http代理

現在,代理正常工作,當我只是通過所有內容。但是,當我嘗試過濾XML文件它並不實際發送內容到客戶端?

下面是一些代碼:

內螺紋run()方法接受Socket連接時所衍生,一旦予確定所述請求是針對我要篩選的文件,我稱:

filterRaceFile(serverIn, clientOut);  // This won't send content  
//streamHTTPData(serverIn, clientOut, true); // This passes through fine (but all content of course). 

,這裏是過濾方法本身:

private void filterRaceFile(InputStream is, OutputStream os) { 
    // Pass through headers before using deflate and filtering xml 
    processHeader(is, os, new StringBuilder(), new StringBuilder());   

    // Seems to be 1 line left, inflater doesn't like it if we don't do this anyway...? 
    try { 
     os.write(readLine(is, false).getBytes()); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    }  

    InflaterInputStream inflate = new InflaterInputStream(is); 
    DeflaterOutputStream deflate = new DeflaterOutputStream(os); 
    int c = 0; 
    try { 
     DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
     Document xdoc = db.parse(inflate); 
     Node id = xdoc.getElementsByTagName("id").item(0); 
     Node msg = xdoc.getElementsByTagName("message").item(0); 
     StringBuilder xml_buf = new StringBuilder("<race>\n"); 

     xml_buf.append("<id>").append(id.getTextContent()).append("</id>\n"); 
     xml_buf.append("<message>").append(msg.getTextContent()).append("</message>\n"); 
     xml_buf.append("<boats>\n"); 

     NodeList allBoats = xdoc.getElementsByTagName("boat"); 
     int N = allBoats.getLength(); 

     for (int i = 0; i < N; ++i) 
     { 
      Node boat = allBoats.item(i); 
      Element boat_el = (Element)boat;     
      double lat = Double.parseDouble(boat_el.getElementsByTagName("lat").item(0).getTextContent()); 
      double lon = Double.parseDouble(boat_el.getElementsByTagName("lon").item(0).getTextContent()); 
      double dist = Geodesic.vincenty_earth_dist(proxy.userLat, proxy.userLon, lat, lon)[0]; 
      if (dist <= LOS_DIST) 
      { 
       String boatXML = xmlToString(boat); 
       //<?xml version="1.0" encoding="UTF-8"?> is prepended to the xml 
       int pos = boatXML.indexOf("?>")+2; 
       boatXML = boatXML.substring(pos); 
       xml_buf.append(boatXML); 
       ++c; 
      } 
     } 
     System.out.printf("%d boats within LOS distance\n", c); 

     xml_buf.append("</boats>\n"); 
     xml_buf.append("</race>"); 

     byte[] xml_bytes = xml_buf.toString().getBytes("UTF-8"); 
     deflate.write(xml_bytes); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    // flush the OutputStream and return 
    try { 
     os.flush(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 

我也有過法簡單的通過簡單地寫入服務器的InputStream到客戶端的OutputStream中,也使用readLine並且工作正常 - 即在瀏覽器中顯示的任何其他url都沒有問題,所以readLine沒問題。布爾參數是讓它知道它正在從deflate流中讀取,因爲它使用內部標記和讀取,這在deflate流中不受支持。

XML是非常簡單的:

<race> 
    {some data to always pass thru} 
    <boats> 
     <boat> 
      <id>1234</id> 
      .... 
      <lat>-23.3456</lat> 
      <lon>17.2345</lon> 
     </boat> 
     {more boat elements} 
    </boats> 
    </race> 

而且它產生我希望它發送給客戶端罰款XML,但客戶就是不接受它(顯示在Web的0內容長度-debugger,儘管在原始響應中沒有Content-Length頭)

任何有關正在發生什麼的想法,或者我應該怎麼做,我不是?

+0

注意:我也嘗試完全重建響應,在客戶端沒有相同的結果... – 2011-02-09 07:01:38

回答

0

我沒有看到任何錯誤,但是如果您已經在使用Document,是不是可以修改文檔,然後使用XML庫將整個文檔寫出來?這似乎比手動XML格式更健壯。

-1

您需要在deflate.write()之後添加對deflate.close()的調用,以刷新輸出並正確關閉流。

+0

我不明白以前的答案如何不真正回答問題是有效的,但我的答案不是。最初的帖子問道:「關於發生了什麼事情的任何想法,或者我應該做什麼,我不是?」答案是他沒有在deflate上調用.close()。 – JimW 2014-12-05 20:23:13