What is the best method to GZIP a JSF-Seam web app pages

前端 未结 8 1714
眼角桃花
眼角桃花 2020-12-06 03:33

I\'m developing an JSF web app on Tomcat, planning to use Seam in the near future, and I want to add compression of our web pages and resources (i.e. Javascript & CSS fi

8条回答
  •  一个人的身影
    2020-12-06 04:20

    I'm happy with the EhCache filter after some hacking. Here is how it works:

    package myapp;
    
    import net.sf.ehcache.constructs.web.GenericResponseWrapper;
    import net.sf.ehcache.constructs.web.ResponseUtil;
    import static org.jboss.seam.ScopeType.STATELESS;
    import org.jboss.seam.annotations.Name;
    import org.jboss.seam.annotations.Scope;
    import org.jboss.seam.annotations.intercept.BypassInterceptors;
    import org.jboss.seam.annotations.web.Filter;
    
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.ByteArrayOutputStream;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import java.util.zip.GZIPOutputStream;
    
    /**
     * Zip content before sending to the browser.
     * 
     * 
     */
    @Name("gzipFilter")
    @Scope(STATELESS)
    @BypassInterceptors
    @Filter(around = "org.jboss.seam.web.ajax4jsfFilterInstantiator")
    public class GzipFilter extends net.sf.ehcache.constructs.web.filter.Filter
    {
    
        private static final Logger LOG = Logger.getLogger(GzipFilter.class.getName());
    
        /**
         * Performs initialisation.
         *
         * @param filterConfig config
         */
        protected void doInit(FilterConfig filterConfig) throws Exception
        {
            //nothing required.
        }
    
    
        /**
         * A template method that performs any Filter specific destruction tasks.
         * Called from {@link #destroy()}
         */
        protected void doDestroy()
        {
            //noop
        }
    
        /**
         * Performs the filtering for a request.
         */
        protected void doFilter(final HttpServletRequest request, final HttpServletResponse response,
                                final FilterChain chain) throws Exception
        {
            if (!isDocStore(request) && !isIncluded(request) && acceptsEncoding(request, "gzip"))
            {
                // Client accepts zipped content
                if (LOG.isLoggable(Level.FINE))
                {
                    LOG.fine(request.getRequestURL() + ". Writing with gzip compression");
                }
    
                // Create a gzip stream
                final ByteArrayOutputStream compressed = new ByteArrayOutputStream();
                final GZIPOutputStream gzout = new GZIPOutputStream(compressed);
    
                // Handle the request
                final GenericResponseWrapper wrapper = new GenericResponseWrapper(response, gzout);
                chain.doFilter(request, wrapper);
                wrapper.flush();
    
                gzout.close();
    
                //return on error or redirect code, because response is already committed
                int statusCode = wrapper.getStatus();
                if (statusCode != HttpServletResponse.SC_OK)
                {
                    return;
                }
    
                //Saneness checks
                byte[] compressedBytes = compressed.toByteArray();
                boolean shouldGzippedBodyBeZero = ResponseUtil.shouldGzippedBodyBeZero(compressedBytes, request);
                boolean shouldBodyBeZero = ResponseUtil.shouldBodyBeZero(request, wrapper.getStatus());
                if (shouldGzippedBodyBeZero || shouldBodyBeZero)
                {
                    compressedBytes = new byte[0];
                }
    
                // Write the zipped body
                //ResponseUtil.addGzipHeader(response);
                response.setHeader("Content-Encoding", "gzip");
                response.setContentLength(compressedBytes.length);
    
    
                response.getOutputStream().write(compressedBytes);
            } else
            {
                // Client does not accept zipped content - don't bother zipping
                if (LOG.isLoggable(Level.FINE))
                {
                    LOG.fine(request.getRequestURL()
                            + ". Writing without gzip compression because the request does not accept gzip.");
                }
                chain.doFilter(request, response);
            }
        }
    
    
        /**
         * Checks if the request uri is an include.
         * These cannot be gzipped.
         *
         * @param request the request
         * @return true if included
         */
        private boolean isIncluded(final HttpServletRequest request)
        {
            final String uri = (String) request.getAttribute("javax.servlet.include.request_uri");
            final boolean includeRequest = !(uri == null);
    
            if (includeRequest && LOG.isLoggable(Level.FINE))
            {
                LOG.fine(request.getRequestURL() + " resulted in an include request. This is unusable, because" +
                        "the response will be assembled into the overrall response. Not gzipping.");
            }
            return includeRequest;
        }
    
        private boolean isDocStore(final HttpServletRequest request)
        {
            return request.getRequestURI().indexOf("/docstore/") > 0;
        }
    
        /**
         * Determine whether the user agent accepts GZIP encoding. This feature is part of HTTP1.1.
         * If a browser accepts GZIP encoding it will advertise this by including in its HTTP header:
         * 

    * * Accept-Encoding: gzip * *

    * Requests which do not accept GZIP encoding fall into the following categories: *

      *
    • Old browsers, notably IE 5 on Macintosh. *
    • Internet Explorer through a proxy. By default HTTP1.1 is enabled but disabled when going * through a proxy. 90% of non gzip requests seen on the Internet are caused by this. *
    * As of September 2004, about 34% of Internet requests do not accept GZIP encoding. * * @param request the request * @return true, if the User Agent request accepts GZIP encoding */ protected boolean acceptsGzipEncoding(HttpServletRequest request) { return acceptsEncoding(request, "gzip"); } }

提交回复
热议问题