public final class CompressingFilter
extends java.lang.Object
implements javax.servlet.Filter
This filter can, based on HTTP headers in a HttpServletRequest
,
compress data written to the HttpServletResponse
, or decompress data read from the request. When
supported by the client browser, this can potentially greatly reduce the
number of bytes written across the network from and to the client. As a
Filter
, this class can also be easily added to any J2EE 1.3+ web
application.
Why might you want to use this solution compared to others?
pjl-comp-filter-XX.jar
file containing CompressingFilter
to your web application's WEB-INF/lib
directory.web.xml
deployment
descriptor:<filter> <filter-name>CompressingFilter</filter-name> <filter-class>com.planetj.servlet.filter.compression.CompressingFilter</filter-class> </filter> ... <filter-mapping> <filter-name>CompressingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
CompressingFilter
supports the following parameters:
compressionThreshold
bytes are written to the response, it will not
be compressed and the response will go to the client unmodified. If 0,
compression always begins immediately. Defaults to 1024.CompressingFilterStats
. Defaults to false.text/html,text/xml
). The filter will attempt to only compress
responses which specify one of these values as its content type, for example
via ServletResponse.setContentType(String)
. Note that the filter does not
know the response content type at the time it is applied, and so must apply
itself and later attempt to disable compression when content type has been
set. This will fail if the response has already been committed. Also note
that this parameter cannot be specified if excludeContentTypes
is
too.Pattern
) which match exactly those paths which should be
compressed by this filter. Anything else will not be compressed. One can also
merely apply the filter to a subset of all URIs served by the web application
using standard filter-mapping
elements in web.xml
; this
element provides more fine-grained control for when that mechanism is
insufficient. "Paths" here means values returned by
HttpServletRequest.getRequestURI()
. Note that the regex must match
the filename exactly; pattern "static" does not match
everything containing the string "static. Use ".*static.*" for that, for
example. This cannot be specified if excludeFileTypes
is too.includePathPatterns
. Only requests with User-Agent
headers
whose value matches one of these regular expressions will be compressed.
Can't be specified if excludeUserAgentPatterns
is too.User-Agent
header matches one of these patterns will not be
compressed.includeUserAgentPatterns
. Requests with User-Agent
headers
whose value matches one of these regular expressions result in a response
that does not contain the Vary-header
Since version 1.8java.util.logging.Logger
will also receive log messages from this
filter.These values are configured in web.xml
as well with init-param
elements:
<filter> <filter-name>CompressingFilter</filter-name> <filter-class>com.planetj.servlet.filter.compression.CompressingFilter</filter-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> </filter>
This filter supports the following compression algorithms when compressing data to the repsonse, as specified in the "Accept-Encoding" HTTP request header:
This filter supports the following compression algorithms when decompressing data from the request body, as specified in the "Content-Encoding" HTTP request header:
An application may force the encoding / compression used by setting an
"Accept-Encoding" value into the request as an attribute under the key
FORCE_ENCODING_KEY
. Obviously this has to be set upstream from the
filter, not downstream.
The filter requires Java 5 and J2EE 1.4 or better.
Note that if this filter decides that it should try to compress the response, it will close the response (whether or not it ends up compressing the response). No more can be written to the response after this filter has been applied; this should never be necessary anyway. Put this filter ahead of any filters that might try to write to the repsonse, since presumably you want this content compressed too anyway.
If a OutputStream.flush()
occurs before the filter has
decided whether to compress or not, it will be forced into compression
mode.
The filter will not compress if the response sets
Cache-Control: no-transform
header in the response.
The filter attempts to modify the ETag
response header, if
present, when compressing. This is because the compressed response must be
considered a separate entity by caches. It simply appends, for example,
"-gzip" to the ETag header value when compressing with gzip. This is not
guaranteed to work in all containers, in the sense that some containers may
not properly associated this ETag with the compressed content and simply
return the response again.
The filter always sets the Vary
response header to indicate that a
different response may be returned based on the Accept-Encoding
header of the request.
Modifier and Type | Field and Description |
---|---|
static java.lang.String |
COMPRESSED_KEY
A request attribute is set under this key with a non-null value if this
filter has applied compression to the response.
|
static java.lang.String |
FORCE_ENCODING_KEY
One may force the filter to use a particular encoding by setting its
value as an attribute of the
ServletRequest passed to this filter, under this key. |
Constructor and Description |
---|
CompressingFilter() |
public static final java.lang.String FORCE_ENCODING_KEY
ServletRequest
passed to this filter, under this key. The value should
be a valid "Accept-Encoding" header value, like "gzip". Specify
"identity" to force no compression.public static final java.lang.String COMPRESSED_KEY
public void init(javax.servlet.FilterConfig config) throws javax.servlet.ServletException
init
in interface javax.servlet.Filter
javax.servlet.ServletException
public void doFilter(javax.servlet.ServletRequest request, javax.servlet.ServletResponse response, javax.servlet.FilterChain chain) throws java.io.IOException, javax.servlet.ServletException
doFilter
in interface javax.servlet.Filter
java.io.IOException
javax.servlet.ServletException
public void destroy()
destroy
in interface javax.servlet.Filter
public java.lang.String toString()
toString
in class java.lang.Object