Java Web 基础 —— 过滤器和监听器
一、过滤器
Servlet过滤器实质上就是在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()可以获取文件名称.