过滤器-监听器-Servlet3.0-文件上传

Filter 即为过滤,用于在 Servlet 之外对 Request 或者 Response 进行修改。它主要用于对用户请
求进行预处理,也可以对 HttpServletResponse 进行后处理。使用 Filter 的完整流程:Filter 对用户请
求进行预处理,接着将请求交给 Servlet 进行处理并生成响应,最后 Filter 再对服务器响应进行后处
理。在一个 web 应用中,可以开发编写多个 Filter,这些 Filter 组合起来称之为一个 Filter 链。
单个过滤器

若是一个过滤器链:先配置先执行(请求时的执行顺序);响应时:以相反的顺序执行。
  在 HttpServletRequest 到达 Servlet 之前,拦截客户的 HttpServletRequest 。根据需要检查
HttpServletRequest,也可以修改 HttpServletRequest 头和数据。
  在HttpServletResponse 到达客户端之前,拦截 HttpServletResponse。根据需要检查
HttpServletResponse,也可以修改 HttpServletResponse 头和数据。
3.2 实现
  我们可以通过实现一个叫做 javax.servlet.Fileter 的接口来实现一个过滤器,其中定义了三个方
法,init(), doFilter(), destroy() 分别在相应的时机执行。后期观察生命周期。Filter 的实现只需要两
步:
  Step1: 编写 java 类实现 Filter 接口,并实现其 doFilter 方法。
  Step2: 在 web.xml 文件中对编写的 filter 类进行注册,并设置它所能拦截的资源。
public class Filter01 implements Filter {
/**

  • 初始化,只执行一次
    /
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println(“Filter01 init…”);
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
    FilterChain chain) throws IOException, ServletException {
    System.out.println(“Filter01”);
    // 请求到达资源之前处理的代码
    System.out.println(“Filter01 请求到达资源之前处理的代码…”);
    // 放行
    chain.doFilter(request, response);
    // 响应到客户端之前执行的代码
    System.out.println(“Filter01 响应到客户端之前执行的代码…”);
    }
    /
    *
      Filter 接口中有一个 doFilter 方法,当开发人员编写好 Filter,并配置对哪个 web 资源进行拦截
    后,Web 服务器每次在调用 web 资源的 service 方法之前,都会先调用一下 filter 的 doFilter 方法。
    因此可以达到如下效果:
      调用目标资源之前,让一段代码执行。
      是否调用目标资源(即是否让用户访问 web 资源)。
      web 服务器在调用 doFilter 方法时,会传递一个 filterChain 对象进来,filterChain 对象是 filter
    接口中最重要的一个对象,它提供了一个 doFilter 方法,开发人员可以根据需求决定是否调用此方
    法,调用该方法,则 web 服务器就会调用 web 资源的 service 方法,即 web 资源就会被访问,否则
    web 资源不会被访问。(本质是放行,调用 doFilter 方法后,即请求可以到达资源)
    web.xml 配置各节点说明:
  • 销毁,只执行一次
    /
    @Override
    public void destroy() {
    System.out.println(“Filter01 destroy…”);
    }
    }

    filter01
    com.shsxt.filter.Filter01


    filter01
    /s01

    指定一个过滤器。
    用于为过滤器指定一个名字,该元素的内容不能为空。
    元素用于指定过滤器的完整的限定类名。
    元素用于为过滤器指定初始化参数,它的子元素
    指定参数的名字,
    指定参数的值。
    在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。
    元素用于设置一个Filter所负责拦截的资源。一个Filter拦截的资源可通过两种方式
    来指定:Servlet 名称和资源访问的请求路径
    子元素用于设置filter的注册名称。该值必须是在元素中声明过的过滤器
    的名字
    设置filter所拦截的请求路径(过滤器关联的URL样式)
    指定过滤器所拦截的Servlet名称。
    指定过滤器所拦截的资源被Servlet容器调用的方式,可以是
    REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个子元素用来
    指定Filter对资源的多种调用方式进行拦截。
    子元素可以设置的值及其意义
    REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过
    RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
    INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器
    将被调用。除此之外,该过滤器不会被调用。
    FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器
    将被调用,除此之外,该过滤器不会被调用。
      url-pattern 的配置:
      ①配置具体路径 /index.html /TestServlet.do
      ②带有通配符的配置 .do / /user/
    *.html .jsp
    3.3 过滤器执行的顺序
      通过观察 web.xml 中的配置和各个 filter 的执行顺序,找出 filter 执行先后的依据。根据之前观察
    Servlet 生命周期的方式,观察一下过滤器的生命周期。
    3.4 过滤器处理字符乱码
      注意:Tomcat7 及以下的版本:上述解决 GET 乱码的方式不好,不能解决所有的问题,可以借助
    HttpServletRequestWrapper 类和过滤器来完成转换乱码的问题:
      ①在过滤器中判断哪些需要解决
      ②定义 HttpServletRequestWrapper 的子类,并且重写 getParameter(String name) 方法,在该
    方法中实现乱码的处理
      ③chain.doFilter(自定义类(HttpServletRequestWrapper 的子类),response)
    四、监听器
    4.1 介绍
      web 监听器是一种 Servlet 中的特殊的类,它们能帮助开发者监听 web 中的特定事件,比如
    ServletContext,HttpSession,ServletRequest 的创建和销毁;变量的创建、销毁和修改等。可以在某些
    动作前后增加处理,实现监控。例如可以用来统计在线人数等。
    ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过
    滤器不会被调用。
    GET:
    请求:
    Tomcat8及以上,不需要处理
    Tomcat7及以下,需要处理乱码
    new String(request.getParameter(name).getBytes(“ISO-8859-1”),“UTF-8”);
    响应:
    response.setContentType(“text/html;charset=UTF-8”);
    POST:
    请求:
    Tomcat8及以上,需要处理乱码,request.setCharacterEncoding(“UTF-8”);
    Tomcat7及以下,需要处理乱码,request.setCharacterEncoding(“UTF-8”);
    响应:
    response.setContentType(“text/html;charset=UTF-8”);
    4.2 实现
      监听器有三类8种:
      ⑴监听生命周期(三个域对象的创建和销毁):实现接口 ServletRequestListener、
    HttpSessionListener 、ServletContextListener
      ⑵监听值的变化(属性添加,移除,替换):实现接口 ServletRequestAttributeListener、
    HttpSessionAttributeListener、ServletContextAttributeListener
      ⑶针对 session 中的对象:监听 session 中的 java 对象(javaBean),javaBean 直接实现监听器的
    接口 HttpSessionBindingListener、HttpSessionActivationListener。这里我们只做一个简单的演示。
    假设我们想做一个对在线人数的监控。
      Step1:创建一个监听器,需要实现某种接口,根据需求选取 HttpSessionListener
      Step2:在 web.xml 中配置该监听器
      创建一个类,并实现 HttpSessionListener 接口,用来检测 Session 的创建和销毁。在类中定义一
    个成员变量用来存储当前的 session 个数。
    在 web.xml 中配置该监听器,让监听器生效
    做一个测试的 Servlet 用来访问,和显示当前在线人数
    public class OnlineListener implements HttpSessionListener {
    private int onlineNumber = 0;
    @Override
    public void sessionCreated(HttpSessionEvent se) {
    System.out.println(“session创建时调用…”);
    onlineNumber++; // 每次创建session对象时,人数+1
    se.getSession().setAttribute(“onlineNumber”, onlineNumber);
    }
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
    System.out.println(“session销毁时调用…”);
    onlineNumber–; // 每次销毁session对象时,人数-1
    se.getSession().setAttribute(“onlineNumber”, onlineNumber);
    }
    }

    com.shsxt.listener.OnlineListener

    public class OnlineServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void service(HttpServletRequest request, HttpServletResponse
    response) throws ServletException, IOException {
    // 得到session对象
    HttpSession session = request.getSession();
    // 得到session作用域中的值
    访问并测试结果
    五、Servlet3.0 注解
      在 Servlet3.0 之前一直使用的都是配置文件的方式来实现各种组件,Servlet3.0 之后提供了注解,
    可以达到零配置。但现实中一般是注解+配置结合使用。我们看几个常用的注解。
    5.1 @WebServlet
      在Servlet3.0中,可以使用 @WebServlet 注解将一个继承于 javax.servlet.http.HttpServlet 的类标
    注为可以处理用户请求的 Servlet,无需配置 web.xml。
    用注解配置 Servlet
    也可以配置多个 urlPatterns 来指定多个访问路径
    int onlineNumber = (int) session.getAttribute(“onlineNumber”);
    // 显示在页面上
    response.setContentType(“text/html;charset=UTF-8”);
    response.getWriter().write(“

    当前在线 " + onlineNumber + " 人

    ”);
    }
    }
    @WebServlet(name = “servlet01”,value = “/s01”)
    public class Servlet01 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void service(HttpServletRequest request, HttpServletResponse
    response) throws ServletException, IOException {
    System.out.println(“Servlet01…”);
    }
    }
    @WebServlet(name = “servlet01”,urlPatterns = {"/s01","/s001"})
    public class Servlet01 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void service(HttpServletRequest request, HttpServletResponse
    response) throws ServletException, IOException {
    System.out.println(“Servlet01…”);
    }
    }
    5.2 @WebFilter
    @WebFilter 用来配置过滤器
    使用注解时:过滤器链按照类名的字母排序(大部分情况)
    5.3 @WebListener
      Servlet3.0 提供 @WebListener 注解将一个实现了特定监听器接口的类定义为监听器。比如将实现
    了 ServletSessionListener 接口的类标注为监听器。
    5.4 @MultipartConfig
      使用注解 @MultipartConfig 将一个 Servlet 标识为支持文件上传。Servlet3.0 将 multipart/formdata 的 POST 请求封装成 Part,通过 Part 对上传的文件进行操作。
    前台
    @WebFilter(filterName = “filter01”,urlPatterns = "/")
    public class Filter01 implements Filter {
    public void destroy() {
    }
    public void doFilter(ServletRequest request, ServletResponse response,
    FilterChain chain) throws IOException, ServletException {
    System.out.println(“Filter01…”);
    chain.doFilter(request, response);
    }
    public void init(FilterConfig fConfig) throws ServletException {
    }
    }
    @WebListener
    public class Listener02 implements HttpSessionListener {
    public void sessionCreated(HttpSessionEvent se) {
    }
    public void sessionDestroyed(HttpSessionEvent se) {
    }
    }
后台 注解除了学的这些,重要的是以后学会根据注解的定义配置注解。 上传文件 姓名: 文件: 注解除了学的这些,重要的是以后学会根据注解的定义配置注解。 @WebServlet("/upload") @MultipartConfig public class UploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void service(HttpServletRequest request, Htresponse) throws ServletException, IOException { System.out.println("上传文件..."); // 设置编码 request.setCharacterEncoding("UTF-8"); // 获取普通表单项参数 String uname = request.getParameter("uname"); System.out.println(uname); // 上传文件 // 得到part对象 request.getpart(name):name代表的是表Part part = request.getPart("myfile"); // 得到文件存放的路径 String path = request.getServletContext().getReal// 得到文件名 String fileName = part.getSubmittedFileName(); // 上传 part.write(path + fileName); } }

你可能感兴趣的:(servlet,tomcat,过滤器)