public
void
doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws
ServletException, IOException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
if
(isUnusualCondition(req)) {
res.sendRedirect(
"http://www.somesite.com"
);
}
else
{
chain.doFilter(req, res);
}
}
|
package
com.zj.sample;
import
java.io.IOException;
import
java.io.PrintWriter;
import
java.net.MalformedURLException;
import
java.net.URL;
import
java.util.HashSet;
import
java.util.StringTokenizer;
import
javax.servlet.Filter;
import
javax.servlet.FilterChain;
import
javax.servlet.FilterConfig;
import
javax.servlet.ServletException;
import
javax.servlet.ServletRequest;
import
javax.servlet.ServletResponse;
import
javax.servlet.http.HttpServletRequest;
public
class
BannedAccessFilter
implements
Filter {
private
HashSet<String>
bannedSiteTable
;
/**
*
Deny
access
if
the
request
comes
from
a
banned
site
or
is
referred
here
*
by
a
banned
site.
*/
public
void
doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws
ServletException, IOException {
System.
out
.println(
"Within BannedAccessFilter:Filtering the Request..."
);
HttpServletRequest req = (HttpServletRequest) request;
String requestingHost = req.getRemoteHost();
String referringHost = getReferringHost(req.getHeader(
"Referer"
));
String bannedSite =
null
;
boolean
isBanned =
false
;
if
(
bannedSiteTable
.contains(requestingHost)) {
bannedSite = requestingHost;
isBanned =
true
;
}
else
if
(
bannedSiteTable
.contains(referringHost)) {
bannedSite = referringHost;
isBanned =
true
;
}
if
(isBanned) {
showWarning(response, bannedSite);
}
else
{
chain.doFilter(request, response);
}
System.
out
.println(
"Within BannedAccessFilter:Filtering the Response..."
);
}
/**
*
Create
a
table
of
banned
sites
based
on
initialization
parameters.
*
Remember
that
version
2.3
of
the
servlet
API
mandates
the
use
of
the
*
Java
2
Platform.
Thus,
it
is
safe
to
use
HashSet
(which
determines
*
whether
a given
key
exists)
rather
than
the
clumsier
Hashtable
*
(which
has
a
value
for
each
key).
*/
public
void
init(FilterConfig config)
throws
ServletException {
bannedSiteTable
=
new
HashSet<String>();
String bannedSites = config.getInitParameter(
"bannedSites"
);
// Default token set: white space.
StringTokenizer tok =
new
StringTokenizer(bannedSites);
while
(tok.hasMoreTokens()) {
String bannedSite = tok.nextToken();
bannedSiteTable
.add(bannedSite);
System.
out
.println(
"Banned "
+ bannedSite);
}
}
public
void
destroy() {}
private
String getReferringHost(String refererringURLString) {
try
{
URL referringURL =
new
URL(refererringURLString);
return
(referringURL.getHost());
}
catch
(MalformedURLException mue) {
// Malformed or null
return
(
null
);
}
}
// Replacement response that is returned to users
// who are from or referred here by a banned site.
private
void
showWarning(ServletResponse response, String bannedSite)
throws
ServletException, IOException {
response.setContentType(
"text/html"
);
PrintWriter out = response.getWriter();
String docType =
"<!DOCTYPE HTML PUBLIC \"-//W 3C //DTD HTML 4.0 "
+
"Transitional//EN\">\n"
;
out.println(docType +
"<HTML>\n"
+
"<HEAD><TITLE>Access Prohibited</TITLE></HEAD>\n"
+
"<BODY BGCOLOR=\"WHITE\">\n"
+
"<H1>Access Prohibited</H1>\n"
+
"Sorry, access from or via "
+ bannedSite +
"\n"
+
"is not allowed.\n"
+
"</BODY></HTML>"
);
}
}
|
<
filter
>
<
filter-name
>
BannedAccessFilter
</
filter-name
>
<
filter-class
>
com.zj.sample.BannedAccessFilter
</
filter-class
>
<
init-param
>
<
param-name
>
bannedSites
</
param-name
>
<
param-value
>
[url]www.competingsite.com[/url] [url]www.bettersite.com[/url]
[url]www.moreservlets.com[/url] 127.0.0.1
//
我们测试这个
</
param-value
>
</
init-param
>
</
filter
>
<
filter-mapping
>
<
filter-name
>
BannedAccessFilter
</
filter-name
>
<
url-pattern
>
/*
</
url-pattern
>
</
filter-mapping
>
|
package
com.zj.sample;
import
java.io.CharArrayWriter;
import
java.io.PrintWriter;
import
javax.servlet.http.HttpServletResponse;
import
javax.servlet.http.HttpServletResponseWrapper;
/**
*
A
response
wrapper
that
takes
everything
the
client
would
normally
* output
and
saves
it
in
one
big
character
array.
*/
public
class
CharArrayWrapper
extends
HttpServletResponseWrapper {
private
CharArrayWriter
charWriter
;
/**
*
Initializes
wrapper.
*
<P>
*
First,
this
constructor
calls
the
parent
constructor.
That
call
*is
crucial
so
that
the
response
is
stored
and
thus
setHeader,
*setStatus,
addCookie,
and
so
forth
work
normally.
*
<P>
*
Second,
this
constructor
creates
a
CharArrayWriter
that
will
*
be
used
to
accumulate
the
response.
*/
public
CharArrayWrapper(HttpServletResponse response) {
super
(response);
charWriter
=
new
CharArrayWriter();
}
/**
*
When
servlets
or
JSP
pages
ask
for
the
Writer,
don't
give
them
*
the
real
one.
Instead,
give
them
a
version
that
writes
into
*
the
character
array.
*
The
filter
needs
to
send
the
contents
of
the
array
to
the
*
client
(perhaps
after
modifying
it).
*/
public
PrintWriter getWriter() {
return
(
new
PrintWriter(
charWriter
));
}
/**
*
Get
a
String
representation
of
the
entire
buffer.
*
<P>
*
Be
sure
<B>
not
</B>
to
call
this
method
multiple
times
on
the
same
*
wrapper.
The
API
for
CharArrayWriter
does
not
guarantee
that
it
*
"remembers"
the
previous
value,
so
the
call
is
likely
to
make
*
a
new
String
every
time.
*/
public
String toString() {
return
(
charWriter
.toString());
}
/**
Get
the
underlying
character
array.
*/
public
char
[] toCharArray() {
return
(
charWriter
.toCharArray());
}
}
|
package
com.zj.sample;
import
java.io.IOException;
import
java.io.PrintWriter;
import
javax.servlet.Filter;
import
javax.servlet.FilterChain;
import
javax.servlet.FilterConfig;
import
javax.servlet.ServletException;
import
javax.servlet.ServletRequest;
import
javax.servlet.ServletResponse;
import
javax.servlet.http.HttpServletResponse;
/**
*
Filter
that
replaces
all
occurrences
of
a
given
string
with
a
*
replacement.
*
This
is
an
abstract
class:
you
<I>
must
</I>
override
the
getTargetString
*
and getReplacementString
methods
in
a
subclass.
* The
first
of
these
methods
specifies
the
string
in
the
response
*
that
should
be
replaced.
The
second
of
these
specifies
the
string
*
that
should
replace
each
occurrence
of
the
target
string.
*/
public
abstract
class
ReplaceFilter
implements
Filter {
private
FilterConfig
config
;
public
void
doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws
ServletException, IOException {
CharArrayWrapper responseWrapper =
new
CharArrayWrapper(
(HttpServletResponse) response);
// Invoke resource, accumulating output in the wrapper.
chain.doFilter(request, responseWrapper);
// Turn entire output into one big String.
String responseString = responseWrapper.toString();
// In output, replace all occurrences of target string with replacement
// string.
responseString = FilterUtils.replace(responseString, getTargetString(),
getReplacementString());
// Update the Content-Length header.
updateHeaders(response, responseString);
PrintWriter out = response.getWriter();
out.write(responseString);
}
/**
*
Store
the
FilterConfig
object
in
case
subclasses
want
it.
*/
public
void
init(FilterConfig config)
throws
ServletException {
this
.
config
= config;
}
protected
FilterConfig getFilterConfig() {
return
(
config
);
}
public
void
destroy() {
}
/**
*
The
string
that
needs
replacement.
*Override
this
method
in
your
subclass.
*/
public
abstract
String getTargetString();
/**
*
The
string
that
replaces
the
target.
Override
this
method
in
*
your subclass.
*/
public
abstract
String getReplacementString();
/**
*
Updates
the
response
headers.
This
simple
version
just
sets
*the
Content
-
Length
header,
assuming
that
we
are
using
a
*character
set
that
uses
1
byte
per
character.
* For
other
character
sets,
override
this
method
to
use
* different
logic
or
to
give
up
on
persistent
HTTP
connections.
*
In
this
latter
case,
have
this
method
set
the
Connection
header
*
to
"close".
*/
public
void
updateHeaders(ServletResponse response, String responseString) {
response.setContentLength(responseString.length());
}
}
|
package
com.zj.sample;
/**
*
Small
utility
to
assist
with
response
wrappers
that
return
strings.
*/
public
class
FilterUtils {
/**
*
Change
all
occurrences
of
orig
in
mainString
to
replacement.
*/
public
static
String replace(String mainString, String orig,
String replacement) {
String result =
""
;
int
oldIndex = 0;
int
index = 0;
int
origLength = orig.length();
while
((index = mainString.indexOf(orig, oldIndex)) != -1) {
result = result + mainString.substring(oldIndex, index)
+ replacement;
oldIndex = index + origLength;
}
result = result + mainString.substring(oldIndex);
return
(result);
}
}
|
package
com.zj.sample;
public
class
ReplaceSiteNameFilter
extends
ReplaceFilter {
public
String getTargetString() {
return
(
"google.com.cn"
);
}
public
String getReplacementString() {
return
(
"baidu.com"
);
}
}
|
<
filter
>
<
filter-name
>
ReplaceSiteNameFilter
</
filter-name
>
<
filter-class
>
com.zj.sample.ReplaceSiteNameFilter
</
filter-class
>
</
filter
>
<
filter-mapping
>
<
filter-name
>
ReplaceSiteNameFilter
</
filter-name
>
<
url-pattern
>
/login.jsp
</
url-pattern
>
</
filter-mapping
>
|
package
com.zj.sample;
import
java.io.ByteArrayOutputStream;
import
java.io.IOException;
import
java.io.OutputStream;
import
java.io.OutputStreamWriter;
import
java.util.zip.GZIPOutputStream;
import
javax.servlet.Filter;
import
javax.servlet.FilterChain;
import
javax.servlet.FilterConfig;
import
javax.servlet.ServletException;
import
javax.servlet.ServletRequest;
import
javax.servlet.ServletResponse;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
/**
*
Filter
that
compresses
output
with
gzip
(assuming
that
browser
supports
*
gzip).
*/
public
class
CompressionFilter
implements
Filter {
private
FilterConfig
config
;
/**
*
If
browser
does
not
support
gzip,
invoke
resource
normally.
If
browser
*
<I>
does
</I>
support
gzip,
set
the
Content
-
Encoding
response
header
and
*
invoke
resource
with
a
wrapped
response
that
collects
all
the
output.
*
Extract
the
output
and
write
it
into
a
gzipped
byte
array.
Finally,
write
*
that
array
to
the
client's
output
stream.
*/
public
void
doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws
ServletException, IOException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
if
(!isGzipSupported(req)) {
// Invoke resource normally.
chain.doFilter(req, res);
}
else
{
// Tell browser we are sending it gzipped data.
res.setHeader(
"Content-Encoding"
,
"gzip"
);
// Invoke resource, accumulating output in the wrapper.
CharArrayWrapper responseWrapper =
new
CharArrayWrapper(res);
chain.doFilter(req, responseWrapper);
// Get character array representing output.
char
[] responseChars = responseWrapper.toCharArray();
// Make a writer that compresses data and puts it into a byte array.
ByteArrayOutputStream byteStream =
new
ByteArrayOutputStream();
GZIPOutputStream zipOut =
new
GZIPOutputStream(byteStream);
OutputStreamWriter tempOut =
new
OutputStreamWriter(zipOut);
// Compress original output and put it into byte array.
tempOut.write(responseChars);
// Gzip streams must be explicitly closed.
tempOut.close();
// Update the Content-Length header.
res.setContentLength(byteStream.size());
// Send compressed result to client.
OutputStream realOut = res.getOutputStream();
byteStream.writeTo(realOut);
}
}
/**
*
Store
the
FilterConfig
object
in
case
subclasses
want
it.
*/
public
void
init(FilterConfig config)
throws
ServletException {
this
.
config
= config;
}
protected
FilterConfig getFilterConfig() {
return
(
config
);
}
public
void
destroy() {}
private
boolean
isGzipSupported(HttpServletRequest req) {
String browserEncodings = req.getHeader(
"Accept-Encoding"
);
return
((browserEncodings !=
null
) && (browserEncodings.indexOf(
"gzip"
) != -1));
}
}
|
package
com.zj.sample;
import
java.io.IOException;
import
java.io.PrintWriter;
import
javax.servlet.ServletException;
import
javax.servlet.http.HttpServlet;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
/**
*
Servlet
with
<B>
long
</B>
output.
Used
to
test
the
effect
of
the
compression
*
filter
of
Chapter
9.
*/
public
class
LongServlet
extends
HttpServlet {
public
void
doGet(HttpServletRequest request, HttpServletResponse response)
throws
ServletException, IOException {
response.setContentType(
"text/html"
);
PrintWriter out = response.getWriter();
String docType =
"<!DOCTYPE HTML PUBLIC \"-//W 3C //DTD HTML 4.0 "
+
"Transitional//EN\">\n"
;
String title =
"Long Page"
;
out.println(docType +
"<HTML>\n"
+
"<HEAD><TITLE>"
+ title
+
"</TITLE></HEAD>\n"
+
"<BODY BGCOLOR=\"#FDF5E6\">\n"
+
"<H1 ALIGN=\"CENTER\">"
+ title +
"</H1>\n"
);
String line =
"Blah, blah, blah, blah, blah. "
+
"Yadda, yadda, yadda, yadda."
;
for
(
int
i = 0; i < 10000; i++) {
out.println(line);
}
out.println(
"</BODY></HTML>"
);
}
}
|
<
filter
>
<
filter-name
>
CompressionFilter
</
filter-name
>
<
filter-class
>
com.zj.sample.CompressionFilter
</
filter-class
>
</
filter
>
<
filter-mapping
>
<
filter-name
>
CompressionFilter
</
filter-name
>
<
servlet-name
>
LongServlet
</
servlet-name
>
</
filter-mapping
>
<
servlet
>
<
servlet-name
>
LongServlet
</
servlet-name
>
<
servlet-class
>
com.zj.sample.LongServlet
</
servlet-class
>
</
servlet
>
<
servlet-mapping
>
<
servlet-name
>
LongServlet
</
servlet-name
>
<
url-pattern
>
/LongServlet
</
url-pattern
>
</
servlet-mapping
>
|