子元素,来说明当前访问的拦截方式。
myfilter
/b.jsp
REQUEST
FORWARD
|
myfilter
/b.jsp
|
myfilter
/b.jsp
FORWARD
|
其实最为常用的就是REQUEST和FORWARD两种拦截方式,而INCLUDE和ERROR都比较少用!ERROR方式如下:
myfilter
/b.jsp
ERROR
500
/b.jsp
|
a.jsp
<%
if(true)
throw new RuntimeException("嘻嘻~");
%>
|
五、过滤器的应用
5.1 获取参数解决全局乱码
public class EncodingRequest extends HttpServletRequestWrapper {
private String charset;
public EncodingRequest(HttpServletRequest request, String charset) {
super(request);
this.charset = charset;
}
public String getParameter(String name) {
HttpServletRequest request = (HttpServletRequest) getRequest();
String method = request.getMethod();
if(method.equalsIgnoreCase("post")) {
try {
request.setCharacterEncoding(charset);
} catch (UnsupportedEncodingException e) {}
} else if(method.equalsIgnoreCase("get")) {
String value = request.getParameter(name);
try {
value = new String(name.getBytes("ISO-8859-1"), charset);
} catch (UnsupportedEncodingException e) {
}
return value;
}
return request.getParameter(name);
}
} |
EncodingFilter
public class EncodingFilter extends HttpFilter {
public void doFilter(HttpServletRequest request,
HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
String charset = this.getInitParameter("charset");
if(charset == null || charset.isEmpty()) {
charset = "utf-8";
}
response.setCharacterEncoding(charset);
response.setContentType("text/html;charset=" + charset);
EncodingRequest res = new EncodingRequest(request, charset);
chain.doFilter(res, response);
}
} |
5.2 自动登录
public class AutoLoginFilter implements Filter {
public void destroy() {
}
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
//读取浏览器中的cookie
Cookie[] cookies = request.getCookies();
//如果有cookie
if(cookies!=null && cookies.length>0){
Cookie usernameCookie = null;
//迭代
for(Cookie c : cookies){
//询找指定的cookie
if("usernameCookie".equals(c.getName())){
//记录已找到的cookie
usernameCookie = c;
//退出
break;
}
}
//如果找到了指定的cookie
if(usernameCookie!=null){
//获取该cookie的值,但此时的值是经过编码后的
String username = usernameCookie.getValue();
//解码
username = URLDecoder.decode(username,"utf-8");
//将用户名绑定HttpSession域对象中
request.getSession().setAttribute("username",username);
//放行请求
chain.doFilter(request,response);
//如果没找到了指定的cookie
}else{
//放行请求
chain.doFilter(request,response);
}
//如果没cookie
}else{
//放行请求
chain.doFilter(request,response);
}
}
}
5.3 数据压缩
public class CharGzipFilter implements Filter {
public void destroy() {
}
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
//创建MyResponse对象
MyResponse myResponse = new MyResponse(response);
//放行请求,即进入charGzip.jsp
chain.doFilter(request,myResponse);
//取出缓存中的数据
byte[] data = myResponse.getData();
//显示
System.out.println("压缩前:"+data.length);
//进行字符压缩,该类只能用于字符流压缩
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(baos);
gzip.write(data);
gzip.flush();
gzip.close();
//从缓存中取出压缩后的字节
data = baos.toByteArray();
//显示
System.out.println("压缩后:"+data.length);
//通知浏览器需要接收GZIP压缩格式的数据
response.setHeader("content-encoding","gzip");
//将压强后的数据输出到浏览器
response.getOutputStream().write(data);
}
}
/**
* 1)写一个普通类继承HttpServletResponseWrapper类
*/
class MyResponse extends HttpServletResponseWrapper{
private PrintWriter pw;
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
private HttpServletResponse response;
public MyResponse(HttpServletResponse response) {
super(response);
this.response = response;
}
/**
* 4)重写父类的getWriter()方法,返回带有缓存的PrintWriter对象
*/
@Override
public PrintWriter getWriter() throws IOException {
pw = new PrintWriter(new OutputStreamWriter(baos,"utf-8"));
return pw;
}
public byte[] getData(){
if(pw!=null){
pw.flush();
}
return baos.toByteArray();
}
}
过滤器除了以上的应用之外,还可以做用户权限的检查、静态资源的缓存优化、拦截器的代理、
等应用操作,在这里就不一一列举了。