下面是一个避免提交数据乱码问题的EncodingFilter:
- package anni;
- import java.io.IOException;
- import javax.servlet.Filter;
- import javax.servlet.FilterChain;
- import javax.servlet.FilterConfig;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- public class EncodingFilter implements Filter {
- public void init(FilterConfig config) throws ServletException {}
- public void destroy() {}
- public void doFilter(ServletRequest request,
- ServletResponse response,
- FilterChain chain)
- throws IOException, ServletException {
- request.setCharacterEncoding("gb2312");
- chain.doFilter(request, response);
- }
- }
package anni; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class EncodingFilter implements Filter { public void init(FilterConfig config) throws ServletException {} public void destroy() {} public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding("gb2312"); chain.doFilter(request, response); } }
相应的web.xml为:
- <filter>
- <filter-name>EncodingFilterfilter-name>
- <filter-class>anni.EncodingFilterfilter-class>
- filter>
- <filter-mapping>
- <filter-name>EncodingFilterfilter-name>
- <url-pattern>/*url-pattern>
- filter-mapping>
EncodingFilter anni.EncodingFilter EncodingFilter /*
过滤控制访问权限的SecurityFilter:
- public void doFilter(ServletRequest request,
- ServletResponse response,
- FilterChain chain)
- throws IOException, ServletException {
- HttpServletRequest req = (HttpServletRequest) request;
- HttpServletResponse res = (HttpServletResponse) response;
- HttpSession session = req.getSession();
- if (session.getAttribute("username") != null) {
- chain.doFilter(request, response);
- } else {
- res.sendRedirect("../failure.jsp");
- }
- }
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; HttpSession session = req.getSession(); if (session.getAttribute("username") != null) { chain.doFilter(request, response); } else { res.sendRedirect("../failure.jsp"); } }
相应的web.xml为:
- <filter>
- <filter-name>SecurityFilterfilter-name>
- <filter-class>anni.SecurityFilterfilter-class>
- filter>
- <filter-mapping>
- <filter-name>SecurityFilterfilter-name>
- <url-pattern>/admin/*url-pattern>
- filter-mapping>
SecurityFilter anni.SecurityFilter SecurityFilter /admin/*
EncodingFilter负责设置编码,SecurityFilter负责控制权限,那这两个过滤器是怎么起作用的呢?它们两个同时过滤一个请求时谁先谁后呢?
所有的奥秘就在Filter中的FilterChain中。服务器会按照web.xml中过滤器定义的先后循序组装成一条链,然后一次执行其中的 doFilter()方法。执行的顺序就如上图所示,执行第一个过滤器的chain.doFilter()之前的代码,第二个过滤器的 chain.doFilter()之前的代码,请求的资源,第二个过滤器的chain.doFilter()之后的代码,第一个过滤器的 chain.doFilter()之后的代码,最后返回响应。
因此在07-02中执行的代码顺序是:
-
执行EncodingFilter.doFilter()中chain.doFilter()之前的部分:request.setCharacterEncoding("gb2312");
-
执行SecurityFilter.doFilter()中chain.doFilter()之前的部分:判断用户是否已登录。
如果用户已登录,则访问请求的资源:/admin/index.jsp。
如果用户未登录,则页面重定向到:/failure.jsp。
-
执行SecurityFilter.doFilter()中chain.doFilter()之后的部分:这里没有代码。
-
执行EncodingFilter.doFilter()中chain.doFilter()之后的部分:这里也没有代码。
过滤链的好处是,执行过程中任何时候都可以打断,只要不执行chain.doFilter()就不会再执行后面的过滤器和请求的内容。而在实际使用时,就要特别注意过滤链的执行顺序问题,像EncodingFilter就一定要放在所有Filter之前,这样才能确保在使用请求中的数据前设置正确的编码。
阅读(1171) | 评论(0) | 转发(0) |