Java Web 基础 —— 过滤器和监听器

一、过滤器

    Servlet过滤器实质上就是在Web应用上用于拦截服务端(浏览器) 与目标资源的请求,并对这些请求进行一定的过滤处理再发给目标资源,处理方式如下图:

Java Web 基础 —— 过滤器和监听器

Java Web 基础 —— 过滤器和监听器

    如果一个过滤器不能解决世纪中的业务需要,可以部署多个过滤器,过滤器处理顺序为在xml定义的顺序,下文会讲到。

1、Filter接口

 

方法声明 说明
public void init(FilterConfig filterConfig) throws ServletException 过滤器初始化方法,在过滤器初始化时调用
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException 对请求进行过滤处理
public void destroy() 销毁方法,,

2、FilterConfig接口

方法声明 说明
public String getFilterName() 用于获取过滤器的名字
public ServletContext getServletContext() 获取Servlet 上下文
public String getInitParamerter(String name) 获取过滤器的初始化参数
public Enumeration getInitParameterNames() 获取过滤器的所有初始化参数

3、FilterChain接口

public void doFilter(ServletRequest request,ServletResponse response) throws IOException,ServletException 将过滤后的请求传递给下一个过滤器,如果是最后一个过滤器,则传送给目标资源

4、字符编码过滤器

//CharactorFilter.java

package CharactFilter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter(filterName = "CharactorFilter")
public class CharactorFilter implements Filter {

    private String encoding = null;

    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        if(encoding != null){
            // 设置传输进来的数据的编码格式
            req.setCharacterEncoding(encoding);
            resp.setContentType("text/html;charset=" + encoding);
        }
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {
        encoding = config.getInitParameter("encoding");
    }

}
<!--web.xml-->
 <filter>
        <filter-name>CharactorFilter</filter-name>
        <filter-class>CharactFilter.CharactorFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharactorFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

  其中,url-pattern可以使用正则表达式进行配置,filter链的顺序是根据web.xml 中filter的顺序来定的.

二、监听器

  1、Servlet 上下文监听

I、ServletContextListener接口

方法声明 说明 
contextInitialize(ServletContextEvent event) 通知正在收听的对象,应用程序已经被加载初始化
contextDestroyed(ServletContextEvent event) 通知正在收听的对象,应用程序已经被载出

II、ServletAttributeListener接口

说明 
attributeAdded(ServletContextAttributeEvent event) 当有对象加入Applicaiton范围,通知
attributeReplaced(ServletContextAttributeEvent event) 当有对象被取代,通知

除此之外,还有HTTP会话监听和Servlet请求监听,详细见文档

三、Servlet3.0新特性

  1、新增注解,在Servlet、Filter、Listener上方添加@Web...注解,就可以不用在xml配置,例如:

package example8;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;


/*
  注解还有urlPatterns,initParms,asyncSupport等属性
*/ 
@WebServlet(name = "MyServlet")
public class MyServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        response.setCharacterEncoding("GBK");
        PrintWriter out = response.getWriter();
        out.println("Servlet实例");
        out.print(this.getClass());
        out.flush();
        out.close();
    }
}

2、 对文件上传的支持

  上传文件,需要添加@MultipartConfig注解,从request中获取Part文件对象,@MulitpartConfig在@WebServlet之下,其中属性如下:

属性名 类型 描述
fileSizeThreshold int 当数据量大雨该指时,内容被写入文件
location Strign  存放生成的文件地址
maxFileSize Long 默认-1,表示没有限制,允许文件的最大值
maxRequestSize Long 针对muliiPart/form-data的最大数量,默认值为-1,表示没有限制
<%--
  JSP文件
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
        <form method="post" action="/FileLoad" enctype="multipart/form-data">
            <input type="file" name="file1" id="file1"/>
            <input type="submit" value="提交"/>
        </form>
  </body>
</html>
package FilteUpload;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(name = "UploadServlet")
@MultipartConfig()
public class UploadServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         response.setContentType("text/html;charset=utf-8");

        PrintWriter out = response.getWriter();
        String path = this.getServletContext().getRealPath("/");
        Part p = request.getPart("file1");
        System.out.println(p.getHeaderNames());
        if(p.getContentType().contains("image")){
            String fileName = p.getSubmittedFileName();
            p.write(path + "/upload/" + fileName); // 不能存放不存在的文件夹
            out.write("yes");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

  其中,p.getSubmittedFileName()可以获取文件名称.