微信扫一扫

028-83195727 , 15928970361
business@forhy.com

JavaEE学习笔记之Servlet/JSP(5)

java ee2016-07-10

这里列出在Servlet中常用的几种过滤器:

一、字符编码的过滤器

/**
 * 字符编码的过滤器 用于设置 HTTP 请求字符编码的过滤器,通过过滤器参数encoding指明使用何种字符编码,用于处理HtmlForm请求参数的中文问题 
 */
public class CharacterEncodingFilter implements Filter {

    private FilterConfig config = null;
    private String defaultCharset = "utf-8";

    public CharacterEncodingFilter() {
        // TODO Auto-generated constructor stub
    }

    /**
     * @see Filter#destroy()
     */
    public void destroy() {
        this.config = null;
        this.defaultCharset = null;
    }

    /**
     * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
     */
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        String charset = config.getInitParameter("encoding");

        if (charset == null) {
            charset = defaultCharset;
        }

        request.setCharacterEncoding(charset);
        // 有时候response不用设置编码,因为servlet一般不做输出,
        // 输出交由jsp来做,所以只要jsp页面设定编码即可

        request.setCharacterEncoding(charset);
        resp.setContentType("text/html;charset=" + charset);
        chain.doFilter(req, resp);
    }

    /**
     * @see Filter#init(FilterConfig)
     */
    public void init(FilterConfig fConfig) throws ServletException {
        this.config = fConfig;
    }
}

web.xml

 <filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>com.briup.day03.CharacterEncodingFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

二、禁止缓存所有动态页面的过滤器

a) 有 3 个 HTTP 响应头字段都可以禁止浏览器缓存当前页面,它们在 Servlet 中的示例代码如下:

         response.setDateHeader("Expires",-1);

         response.setHeader("Cache-Control","no-cache"); 

         response.setHeader("Pragma","no-cache"); 

b) 并不是所有的浏览器都能完全支持上面的三个响应头,因此最好是同时使用上面的三个响应头。

c) Expires数据头:值为GMT时间值,为-1指浏览器不要缓存页面

d) Cache-Control响应头有两个常用值:

         no-cache指浏览器不要缓存当前页面。

         max-age:xxx指浏览器缓存页面xxx秒
/**
 *  用于使 Browser 不缓存页面的过滤器 
 */
public class NoCacheFilter implements Filter {

    public NoCacheFilter() {

    }

    public void destroy() {

    }

    public void doFilter(ServletRequest req, ServletResponse resp,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        response.setDateHeader("expires", -1);
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        chain.doFilter(request, response);
    }

    public void init(FilterConfig fConfig) throws ServletException {
    }

}

web.xml

<filter>
    <filter-name>noCacheFilter</filter-name>
    <filter-class>com.briup.day03.NoCacheFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>noCacheFilter</filter-name>
    <url-pattern>*.jsp</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>noCacheFilter</filter-name>
    <url-pattern>/servlet/*</url-pattern>
  </filter-mapping>

可以设置多个filter-mapping来映射不同的文件类型

测试:

提交表单数据,返回,查看表单中的数据是否仍然存在

三、防止用户未登录访问的过滤器

我们可能经常会用到这一功能,比如有时,我们不希望用户没有进行登录访问后台的操作页面,而且这样的非法访问会让系统极为的不安全,所以我们常常需要进行登录才授权访问其它页面,否则只会出现登录页面,当然我的思路:

一种是在jsp页面进行session的判断,如果不存在该用户的session,就跳转到登录页面,否则执行jsp页面代码,但是你会发现这样做逻辑也简单,但是非常麻烦,如果有很多个jsp,那么就要写多个判断

另一种则是利用过滤器,访问页面时都进行过滤验证,如果存在该用户session,则访问该页面,否则跳转到登陆页面登录,保存session后访问其它页面

public class LoginFilter implements Filter {

    public static final String login_page = "/test/admin/index.jsp";
    public static final String logout_page = "/test/admin/Public/login.jsp";

    @Override
    public void destroy() {
        System.out.println("OneFilter 销毁。。。");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        String requestURI = request.getRequestURI();
        String cxtPath = request.getContextPath();
        //除掉项目名称时访问页面当前路径
        String targerURL = requestURI.substring(cxtPath.length());
        HttpSession session = request.getSession(false);
        //对当前页面进行判断,如果当前页面不为登录页面
        if (!("/admin/Public/login.jsp".equals(targerURL))) {
            //在不是登陆页面时,再进行判断,如果不是登陆页面也没有session则跳转到登录页面,
            if(session == null || session.getAttribute("admin") == null){
                response.sendRedirect(logout_page);
                return;
            }else {
                //这里表示正确,会去寻找下一个链,如果不存在,则进行正常的页面跳转
                chain.doFilter(request, response);
                return;
            }
        }else {
            //这里表示如果当前页面是登陆页面,跳转到登陆页面
            chain.doFilter(request, response);
            return;
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        System.out.println("OneFilter 初始化。。。");
    }
}

web.xml

<filter>
    <filter-name>LoginFilter</filter-name>
    <filter-class>com.test.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>LoginFilter</filter-name>
    //这里表示对所有的以jsp后缀的文件有效,其它的无效
    <url-pattern>*.jsp</url-pattern>
</filter-mapping>