2009-04-01 25 views
10

Sin embargo, quiero comprimir mis respuestas con GZIP cuando sea posible. Intenté usar el Compression filter code disponible para descargar gratis en el sitio principal. Funciona muy bien para html, images, css y javascript.Usar respuestas GZIP, JSON y JQuery

A continuación, publico el filtro. Comprueba si GZIP es una codificación aceptada y agrega gzip como Content-Encoding. Ver: 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; 
     } 
    } 

que estaba usando el siguiente código para enviar las respuestas JSON en aplicación web Struts.

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); 
     }    
    } 
} 

Funciona bien sin compresión, pero si puedo comprimir respuestas JSON, no puedo ver mis objetos JSON más. Yo manejo JSON llamadas Ajax con jQuery con fragmentos de código de la siguiente manera:

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

Si veo la respuesta con Firebug está vacío.

¿Debo refractar mi filtro de compresión para omitir la compresión en las respuestas JSON? o hay una solución a esto?

Para mí, parece que JQuery no reconoce la respuesta como JSON porque estoy agregando la compresión Gzip.

+0

Si ejecuta su código sin la parte de compresión, ¿pasa la respuesta satisfactoriamente? –

+0

Sí, todo funciona con JSON funciona bien sin la compresión –

+0

¿Obtuviste una solución para esto? Tengo un problema similar sin resolver. Sería genial si puedes publicar tu respuesta. – Lijo

Respuesta

3

tiene que agregar un encabezado más "content-encoding: gzip" si lo está comprimiendo.

+0

Ya lo hice. Edito mi publicación. Gracias por la respuesta de todos modos. –

0

¿Has probado con un cliente explícito basado en Java para garantizar que sea un problema con jQuery o el navegador? Si el cliente de Java falla, algo está mal con la respuesta del servidor.

Pero supongo que mientras que el navegador puede ocuparse de la descompresión con solicitudes directas, quizás esto no se aplique a las llamadas Ajax.

Es una pregunta interesante, espero que obtengamos una respuesta más definitiva. :)

5

Si veo la respuesta con Firebug, está vacía.

Tiene su idea, no es un problema de JQuery, es del lado del servidor. (Me temo que no puedo ayudarte con eso, aparte de sugerir que dejes de mirar al lado del cliente)

No hay problema para dar gzip respuestas ajax - si no puedes ver la respuesta en Firebug, entonces JQuery tampoco puede verlo.

+0

¿Puede ser después del servidor y antes del cliente? ¿Un problema creado por algunos elementos de red? – Lijo

Cuestiones relacionadas