zoukankan      html  css  js  c++  java
  • 使用Gzip加速网页的传输

    使用Gzip加速网页的传输 - zhiqiangzhan的专栏 - 博客频道 - CSDN.NET

    使用Gzip加速网页的传输


    分类:
    JAVA


    368人阅读
    评论(3)
    收藏
    举报

    博学,切问,近思--詹子知(http://blog.csdn.net/zhiqiangzhan) 

    日前笔者在使用HttpClient在处理大数据请求的时候,在连续发请求的时候经常会出现异常 java.io.IOException: chunked stream ended unexpectedly。使用HttpMethod的abort方法也不能完全避免这种异常的出现,但是对于小数据的请求,这种异常就基本上难得一见了。对于同样的页面请求,如何减少网络的数据传输量呢。众所周知,现在大部分的Web Server都是支持数据的压缩传输的。要知道,一般的网页内容经过压缩,大小可以减少到原来的20%以下,而对于纯英文为网站,网页内容更是可以减少到原来内容的5%以下。而要使Web Server对数据进行压缩传输,只需要在请求头上加入Accept-Encoding:gzip, deflate。

    1. public HttpMethod createHttpMethod(String url, String type, NameValuePair[] params, String contentType) {  
    2.         HttpMethod method = null;  
    3.   
    4.         if (type.equalsIgnoreCase("POST")) {  
    5.             method = new PostMethod(url);  
    6.             method.setRequestHeader("Content-Type", contentType);  
    7.             if(params != null){  
    8.                 ((PostMethod) method).setRequestBody(params);  
    9.             }  
    10.         } else {  
    11.             method = new GetMethod(url);  
    12.             if(params != null){  
    13.                 method.setQueryString(params);  
    14.             }  
    15.         }  
    16.         method.setRequestHeader("Accept-Encoding""gzip, deflate");  
    17.         return method;  
    18.     }  

    这个时候,如果你请求的Web Server支持Gzip,返回来的响应便是被压缩后的数据,那么把压缩后的数据解析成原来的网页内容便是客户端要做的事情了。对于当前的主流浏览器,都是支持对压缩数据自动解压的,而在我们的应用程序中,我们只要对象网页流稍作处理,便可以得到原来的网页内容。

    1. protected String doSuccess(HttpMethod method) throws IOException {  
    2.         InputStream in = method.getResponseBodyAsStream();  
    3.         Header contentEncodingHeader = method.getResponseHeader("Content-Encoding");  
    4.         if (contentEncodingHeader != null) {  
    5.             String contentEncoding = contentEncodingHeader.getValue();  
    6.             if (contentEncoding.toLowerCase(Locale.US).indexOf("gzip") != -1) {  
    7.                 in = new GZIPInputStream(in);  
    8.             }  
    9.         }  
    10.         return decoder.decode(in);  
    11.     }  

    上一篇文章,我们介绍了如何检查文档输入流的编码,本节我们就可以利用上文的HtmlInputStreamDecoder类来把文档流来解析文档内容。完整的代码如下:

    1. import java.io.IOException;  
    2. import java.io.InputStream;  
    3. import java.util.Locale;  
    4. import java.util.zip.GZIPInputStream;  
    5.   
    6. import org.apache.commons.httpclient.Header;  
    7. import org.apache.commons.httpclient.HttpClient;  
    8. import org.apache.commons.httpclient.HttpException;  
    9. import org.apache.commons.httpclient.HttpMethod;  
    10. import org.apache.commons.httpclient.HttpStatus;  
    11. import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;  
    12. import org.apache.commons.httpclient.NameValuePair;  
    13. import org.apache.commons.httpclient.URI;  
    14. import org.apache.commons.httpclient.URIException;  
    15. import org.apache.commons.httpclient.methods.GetMethod;  
    16. import org.apache.commons.httpclient.methods.PostMethod;  
    17. import org.apache.log4j.Logger;  
    18.   
    19. public class HttpRequest {  
    20.     private static final Logger LOGGER = Logger.getLogger(HttpRequest.class);  
    21.     private HttpClient client;  
    22.     private HtmlInputStreamDecoder decoder;  
    23.   
    24.     public HttpRequest() {  
    25.         this(new HttpClient(new MultiThreadedHttpConnectionManager()));  
    26.     }  
    27.   
    28.     public HttpRequest(HttpClient client) {  
    29.         this.client = client;  
    30.         this.decoder = new HtmlInputStreamDecoder();  
    31.     }  
    32.   
    33.     public String doRequest(HttpMethod method) {  
    34.         String html = null;  
    35.         try {  
    36.             int statusCode = client.executeMethod(method);  
    37.             switch (statusCode) {  
    38.             case HttpStatus.SC_OK:  
    39.                 html = doSuccess(method);  
    40.                 break;  
    41.             case HttpStatus.SC_MOVED_PERMANENTLY:  
    42.             case HttpStatus.SC_MOVED_TEMPORARILY:  
    43.             case HttpStatus.SC_SEE_OTHER:  
    44.             case HttpStatus.SC_TEMPORARY_REDIRECT:  
    45.                 doRedirect(method);  
    46.                 break;  
    47.             default:  
    48.                 html = doError(method);  
    49.             }  
    50.         } catch (HttpException e) {  
    51.             LOGGER.error("Http error occur while visit the url.", e);  
    52.         } catch (IOException e) {  
    53.             LOGGER.error("IO error occur while visit the url.", e);  
    54.         } finally {  
    55.             method.abort();  
    56.             method.releaseConnection();  
    57.         }  
    58.         return html;  
    59.     }  
    60.   
    61.     protected String doSuccess(HttpMethod method) throws IOException {  
    62.         InputStream in = method.getResponseBodyAsStream();  
    63.         Header contentEncodingHeader = method.getResponseHeader("Content-Encoding");  
    64.         if (contentEncodingHeader != null) {  
    65.             String contentEncoding = contentEncodingHeader.getValue();  
    66.             if (contentEncoding.toLowerCase(Locale.US).indexOf("gzip") != -1) {  
    67.                 in = new GZIPInputStream(in);  
    68.             }  
    69.         }  
    70.         return decoder.decode(in);  
    71.     }  
    72.   
    73.     protected String doError(HttpMethod method) {  
    74.         LOGGER.error("Error Response: " + method.getStatusLine());  
    75.         return method.getStatusText();  
    76.     }  
    77.   
    78.     protected void doRedirect(HttpMethod method) throws URIException {  
    79.         Header locationHeader = method.getResponseHeader("location");  
    80.         if (locationHeader != null) {  
    81.             String location = locationHeader.getValue();  
    82.             if (location == null) {  
    83.                 location = "/";  
    84.             }  
    85.             doRequest(new GetMethod(getRedirectUrl(method.getURI(), location)));  
    86.         }  
    87.     }  
    88.   
    89.     public HttpMethod createHttpMethod(String url, String type, NameValuePair[] params, String contentType) {  
    90.         HttpMethod method = null;  
    91.   
    92.         if (type.equalsIgnoreCase("POST")) {  
    93.             method = new PostMethod(url);  
    94.             method.setRequestHeader("Content-Type", contentType);  
    95.             if(params != null){  
    96.                 ((PostMethod) method).setRequestBody(params);  
    97.             }  
    98.         } else {  
    99.             method = new GetMethod(url);  
    100.             if(params != null){  
    101.                 method.setQueryString(params);  
    102.             }  
    103.         }  
    104.         method.setRequestHeader("Accept-Encoding""gzip, deflate");  
    105.         return method;  
    106.     }  
    107.   
    108.     protected static String getRedirectUrl(URI origin, String location) throws URIException {  
    109.         String redirect = null;  
    110.         if (location.startsWith("http:")) {  
    111.             redirect = location;  
    112.         } else if (location.startsWith("/")) {  
    113.             origin.setPath(location);  
    114.             redirect = origin.getURI();  
    115.         } else {  
    116.             redirect = origin.getURI().replaceAll("(?<=/)[^/]+$", location);  
    117.         }  
    118.         return redirect;  
    119.     }  
    120.   
    121. }  

    代码示例:

    1. public static void main(String[] args) {  
    2.           
    3.         HttpRequest request = new HttpRequest();  
    4.         HttpMethod method = request.createHttpMethod("http://www.csdn.com""GET"null"text/html");  
    5.           
    6.         String html = request.doRequest(method);          
    7.         System.out.println(html);  
    8.     }  

  • 相关阅读:
    条件语句实例
    数据类型
    C#与.NET概述
    c#循环
    语句
    数组

    英文文献中的数学符号
    如何计算协方差、 协方差矩阵 、 相关系数 、 马氏距离
    opengl 笔记
  • 原文地址:https://www.cnblogs.com/lexus/p/2376783.html
Copyright © 2011-2022 走看看