2009-04-01 91 views
10

しかし、可能な限りGZIPでレスポンスを圧縮したいと思います。私はCompression filter codeをheadfirstサイトで無償でダウンロードしようとしました。それは、HTML、画像、CSSとJavaScriptのために最適です。GZIP、JSONのレスポンスとJQueryの使用

次はフィルタを投稿します。 GZIPが受け入れられたエンコードであるかどうかをチェックし、gzipをContent-Encodingとして追加します。参照:wrappedResp.setHeader("Content-Encoding", "gzip");

public class CompressionFilter implements Filter { 

    private ServletContext ctx; 
    private FilterConfig cfg; 

    /** 
    * The init method saves the config object and a quick reference to the 
    * servlet context object (for logging purposes). 
    */ 
    public void init(FilterConfig cfg) 
    throws ServletException { 
    this.cfg = cfg; 
    ctx = cfg.getServletContext(); 
    //ctx.log(cfg.getFilterName() + " initialized."); 
    } 

     /** 
     * The heart of this filter wraps the response object with a Decorator 
     * that wraps the output stream with a compression I/O stream. 
     * Compression of the output stream is only performed if and only if 
     * the client includes an Accept-Encoding header (specifically, for gzip). 
     */ 
     public void doFilter(ServletRequest req, 
        ServletResponse resp, 
        FilterChain fc) 
     throws IOException, ServletException { 
     HttpServletRequest request = (HttpServletRequest) req; 
     HttpServletResponse response = (HttpServletResponse) resp; 

     // Dose the client accept GZIP compression? 
     String valid_encodings = request.getHeader("Accept-Encoding"); 
     if ((valid_encodings != null) && (valid_encodings.indexOf("gzip") > -1)) { 

      // Then wrap the response object with a compression wrapper 
      // We'll look at this class in a minute. 
      CompressionResponseWrapper wrappedResp = new CompressionResponseWrapper(response); 

      // Declare that the response content is being GZIP encoded. 
      wrappedResp.setHeader("Content-Encoding", "gzip"); 

      // Chain to the next component (thus processing the request) 
      fc.doFilter(request, wrappedResp); 

      // A GZIP compression stream must be "finished" which also 
      // flushes the GZIP stream buffer which sends all of its 
      // data to the original response stream. 
      GZIPOutputStream gzos = wrappedResp.getGZIPOutputStream(); 
      gzos.finish(); 
      // The container handles the rest of the work. 

      //ctx.log(cfg.getFilterName() + ": finished the request."); 

     } else { 
      fc.doFilter(request, response); 
      //ctx.log(cfg.getFilterName() + ": no encoding performed."); 
     } 
     } 

     public void destroy() { 
      // nulling out my instance variables 
      cfg = null; 
      ctx = null; 
     } 
    } 

私はStrutsのWebアプリケーションでJSONレスポンスを送信するために、次のコードを使用していました。

public ActionForward get(ActionMapping mapping, 
    ActionForm  form, 
    HttpServletRequest request, 
    HttpServletResponse response) { 
     JSONObject json = // Do some logic here 
     RequestUtils.populateWithJSON(response, json); 
     return null;   
} 

public static void populateWithJSON(HttpServletResponse response,JSONObject json) { 
    if(json!=null) { 
     response.setContentType("text/x-json;charset=UTF-8");  
     response.setHeader("Cache-Control", "no-cache"); 
     try { 
      response.getWriter().write(json.toString()); 
     } catch (IOException e) { 
      throw new ApplicationException("IOException in populateWithJSON", e); 
     }    
    } 
} 

圧縮なしで正常に動作しますが、JSON応答を圧縮するとJSONオブジェクトが表示されなくなります。

$.post(url,parameters, function(json) { 
    // Do some DOM manipulation with the data contained in the JSON Object 
}, "json"); 

私はFirebugのと応答が表示されている場合は、それが空である:私は次のようにJSON AjaxはコードスニペットでjQueryを使って呼び出しを処理します。

私の圧縮フィルタをJSONレスポンスの圧縮をスキップするように屈折させますか?またはこれに回避策がありますか?

Gzip圧縮を追加しているため、JQueryはレスポンスをJSONとして認識しないようです。

+0

圧縮部分を使わずにコードを実行すると、応答が正常に渡されますか? –

+0

はい、すべてのJSONは、圧縮なしで正常に動作している作品 –

+0

あなたはこれのための解決策を手に入れましたか?私は同様の解決されていない問題があります。あなたの答えを投稿できるなら、それは素晴らしいことでしょう。 – Lijo

答えて

3

圧縮する場合は、もう1つのヘッダー "content-encoding:gzip"を追加する必要があります。

+0

私はすでにやった。私は自分の投稿を編集する。とにかく答えてくれてありがとう。 –

0

明示的なJavaベースのクライアントでjQueryやブラウザに問題がないかどうか確認しましたか? Javaクライアントに障害が発生した場合、サーバーの応答に問題があります。

しかし私はブラウザがダイレクトリクエストで圧縮解除を処理できるのに対し、これはAjaxコールにはあてはまらないと考えています。

興味深い質問ですが、私たちはより明確な答えを得ることを望みます。 :)

5

私がFirebugの応答を見ると、 は空です。

これはJQueryの問題ではなく、サーバー側です。 (私はあなたがクライアント側を見て止めることを提案する以外に、私はそれを助けることはできないと思います)

ajax応答をgzippingしても問題ありません - Firebugで応答が見えない場合はJQueryはそれを見ることもできません。

+0

サーバの後でクライアントの前にすることはできますか?いくつかのネットワーク要素によって解決される問題? – Lijo

関連する問題