3

Tomcat で JSF Web アプリケーションを開発しており、近い将来 Seam を使用する予定です。また、Web ページとリソース (つまり、Javascript と CSS ファイル) の圧縮を追加したいと考えています。Java Web での GZIP 応答に対する 3 つの方法を認識しています。

  1. Ehcache GZIP フィルターを使用します。これは Appfuse で使用されているため、おそらく安定しており、適用前にユーザー エージェントが GZIP をサポートしているかどうかを確認しますが、使用する Seam に問題があるようですhttp://seamframework.org/Community /EHCacheGZipFilterIncompatibleWithSeam .

  2. pjl フィルターを使用します。stackoverflow の質問: Tomcat Compression Does Not Add a Content-Encoding: gzip in the Headerから、メモリ リークはないようですが、Seam に問題があるかどうかはわかりません。

  3. Tomcat のビルトイン圧縮を使用します - コンテンツ エンコーディングを提供しない場合があります (Tomcat 6.0.14 は正常に動作するようですが、ユーザー エージェントの圧縮を適用してはならないブラック リストのみを提供できます。

JSF-Seam 環境でこれらのメソッドを使用した経験のある人はいますか? 「最良の」ソリューションはどれですか?

ありがとう、グレン

4

8 に答える 8

1

フロントエンドを追加nginxして、圧縮 (およびキャッシュ) を実行させるのはどうですか?

http://wiki.nginx.org/Main

この場合、serverfalut に属します :)

于 2009-06-10T20:26:21.967 に答える
1

Jawr APIを試す必要 があります

于 2009-10-15T14:55:00.093 に答える
1

Tomcat のビルトイン圧縮を使用します - コンテンツ エンコーディングを提供しない場合があります (Tomcat 6.0.14 は正常に動作するようですが、ユーザー エージェントの圧縮を適用してはならないブラック リストのみを提供できます。

Tomcat Compression Does Not Add a Content-Encoding: gzip in the Header で見つけた問題を誤解していると思います。この問題は、Tomcat の前で mod_jk を使用して Apache HTTPD を使用することによって発生します。これは、Content-EncodingTomcat からヘッダーを送り返さないように正しく構成されていません。この問題は、Tomcat 自体が原因ではありません。Tomcat はその仕事を完璧にこなしています。

私は、Tomcat の組み込みの圧縮を先に進めてください。compression="on"でHTTP コネクタに属性を追加するのと同じくらい簡単server.xmlです。設定の横にもnoCompressionUserAgents設定がありcompressableMimeTypeます。HTTP コネクタのドキュメントを読んでください。

于 2011-07-28T12:33:29.083 に答える
1

送信トラフィックを圧縮するためJBoss Seamに、on JBoss ASproxied および load balance before apache+ mod_proxy_ajpwithを使用します。mod_deflate

このセットアップの利点

  • ネットにたくさんの例
  • さまざまなユーザー エージェントの癖を考慮した簡単な構成/デバッグ
  • 実行時の構成の変更 (apachectl graceful変更を反映するために webapp/tomcat を再起動する代わりに)。
于 2011-07-28T10:07:06.210 に答える
0

代替のサーブレット フィルターは次の場所にあります。

http://onjava.com/pub/a/onjava/2003/11/19/filters.html

Ehcache と同様に、ブラウザーがサポートしているかどうかをテストします。Seamとの相性は一概には言えませんが、今のところ問題なく使えています。

于 2009-11-03T15:44:48.900 に答える
0

いくつかのハッキングの後、EhCache フィルターに満足しています。仕組みは次のとおりです。

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:
     * <p/>
     * <code>
     * Accept-Encoding: gzip
     * </code>
     * <p/>
     * Requests which do not accept GZIP encoding fall into the following categories:
     * <ul>
     * <li>Old browsers, notably IE 5 on Macintosh.
     * <li>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.
     * </ul>
     * 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");
    }


}
于 2011-07-28T12:49:05.583 に答える
0

GZIP圧縮を追加するためにサーブレットフィルターを試しましたが(Ehcacheではありません)、正しく機能しませんでした。app Server の前に mod_jk を使用して Apache を配置することになりました。GIP 圧縮を構成するのに数分しかかかりませんでした。また、App Server 全体ではなく 1 つのアプリのみが公開されるため、より安全だと感じています。

于 2009-09-23T01:12:35.583 に答える