过滤器Filter

  1. 为什么要有过滤器或者说它在哪里发挥作用? 
  • 字符集过滤器:解决web应用中的请求和响应中中文乱码的问题。
  • 访问权限的限制,比如用户未登录访问资源。

  2. 以字符集过滤器为例,编码:

  • 创建servlet
public class Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        resp.getWriter().print("你好,世界");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 配置web.xml,没有添加过滤器
    <servlet>
        <servlet-name>servlet</servlet-name>
        <servlet-class>per.lc.Servlet.Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>servlet</servlet-name>
        <url-pattern>/hi</url-pattern>
    </servlet-mapping>

结果:页面乱码,这里就不贴图了。

处理办法:

  1.在servlet类中添加resp.setContentType("text/html;charset=utf");

  也能够解决乱码的问题。问题是当项目中有多个servlet时,每个都要去增加这一句,很是麻烦,正确的姿势是使用过滤器。

  2.创建过滤器

  • 继承 javax.servlet中的Filter组件
  • 实现doFilter(),如何过滤的办法体现在这里面。
  • 在web.xml中配置或者以注解的方式
public class CharacterEncodingFilter implements Filter {
    private String characterEncoding="utf-8";
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("拦截开始");
        if(filterConfig.getInitParameter("Encoding")!=null){
            characterEncoding=filterConfig.getInitParameter("Encoding");
        }
    }
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request=(HttpServletRequest)servletRequest;       //servletRequest是HttpServletRequest的超类,这里主要是要处理http协议,就要强转为HttpServletReqest类
        HttpServletResponse response=(HttpServletResponse) servletResponse;
        request.setCharacterEncoding(characterEncoding);
        response.setContentType("text/html;charset="+characterEncoding);
        filterChain.doFilter(request,response);
    }
    public void destroy() {
        System.out.println("拦截结束");
        characterEncoding=null;
    }

//ServletReqest 、HttpServletRequest只是接口,并不去实现接口的方法,方法是由第三方厂商实现的,比如Tomcat,在Catalina.jar 包由对应的方法的实现。
   <filter>
        <filter-name>characterEncoding</filter-name>
        <filter-class>per.lc.FilterDemo.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>Encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
将这段添加到web.xml

 运行程序,中文成功显示出来。

3.<url-pattern>的设置范围:

  • 精确匹配 例如:/xx.jsp
  • 前缀模糊匹配 : /xx/*
  • 后缀模糊匹配: *.jsp
  • 允许组合使用
<url-pattern>/*</url-pattern>
The /* on a servlet overrides all other servlets, including all servlets provided by the servletcontainer such as the default servlet and the JSP servlet. Whatever request you fire, it will end up in that servlet. 
This is thus a bad URL pattern for servlets. Usually, you'd like to use /* on a Filter only. It is able to let the request continue to any of the servlets listening on a more specific URL pattern by calling FilterChain#doFilter().

<url-pattern>/</url-pattern> The / doesn't override any other servlet. It only replaces the servletcontainer's builtin default servlet for all requests which doesn't match any other registered servlet.
This is normally only invoked on static resources (CSS/JS/image/etc) and directory listings. The servletcontainer's builtin default servlet is also capable of dealing with HTTP cache requests, media (audio/video) streaming and file download resumes.
Usually, you don't want to override the default servlet as you would otherwise have to take care of all its tasks, which is not exactly trivial (JSF utility library OmniFaces has an open source example). This is thus also a bad URL pattern for servlets.
As to why JSP pages doesn't hit this servlet, it's because the servletcontainer's builtin JSP servlet will be invoked, which is already by default mapped on the more specific URL pattern *.jsp
英文中的概念暂时不理解,先记住老师讲的。
/* 会拦截所有的请求,包括jsp页面,不建议使用,一般只在过滤器中使用。
/ 只会作用在映射为根路径的servlet
默认首页index.jsp的JSPServlet会覆盖 / 根目录默认的Servlet

 

 

上一篇:javaweb:关于HttpServletRequest介绍 (转)


下一篇:Servlet入门学习(三)