servlet过滤器
servlet过滤器与servlet非常相似,但它有拦截客户端请求的功能,servlet过滤器可以改变请求中的内容来满足实际开发的需求。过滤器实际上就是一个Web应用组件,用于拦截客户端与目标资源的请求,并对这些请求进行一定的过滤处理再发送给目标资源。
Filter接口
过滤器对象放置再javax.servlet包中,其名称为Filter,是一个接口。每一个过滤器对象都需要直接或间接地实现Filter接口,该接口定义3个方法,
public void init(FilterConfig filterConfig) throws ServletException //初始化
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException //对请求进行过滤处理
public void destroy() //销毁方法,以释放资源
编写过滤器时,需要实现Filter接口,并重写这三个方法。在这三个方法中,除了doFilter()方法外,如果业务逻辑中不涉及初始化方法init(),与销毁方法destroy(),可以不编写任何代码对其进行空实现。
FilterConfig接口
FilterConfig接口由Servlet容器进行实现,该接口封装了过滤器中的封装信息,其方法如下:
- public String getFilterName() //用于获取过滤器的名字
- public ServletContext getServletContext() //获取Servlet上下文 public
- String getInitParameter(String name) //获取过滤器初始化参数值 public
- Enumeration getInitParameterNames() //获取过滤器所有初始化参数
FilterChain接口
该接口也是由Servlet容器进行实现,该接口只有一个方法, public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException 该方法用于将过滤后的请求传递给下一个过滤器,如果该过滤器已经是过滤器链中的最后一个过滤器,那么请求将传给目标资源。过滤处理的业务逻辑都编写到doFilter()方法中,在请求过滤处理后,需要调用chain参数的doFilter()方法将请求传递给下一过滤器或者目标资源,否则将出现错误。使用过滤器并不一定要将请求传给下一过滤器或目标资源,如果业务逻辑需要,也可以在过滤处理后,直接回应于客户端。
过滤器的创建与配置
public class MytFilter implements Filter {
@Override
//初始化方法
public void init(FilterConfig filterConfig) throws ServletException {
//初始化处理
}
@Override
//过滤处理方法
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//过滤除磷
// 向下传递过滤器
chain.doFilter(request, response);
}
//销毁方法
@Override
public void destroy() {
//释放资源
}
}
<!-- 过滤器声明 -->
<filter>
<!-- 过滤器的名称 -->
<filter-name>CountFilter</filter-name>
<!-- 过滤器的完整类名 -->
<filter-class>com.lyq.CountFilter</filter-class>
<!-- 设置初始化参数 -->
<init-param>
<!-- 参数名 -->
<param-name>count</param-name>
<!-- 参数值 -->
<param-value>5000</param-value>
</init-param>
</filter>
<!-- 过滤器映射 -->
<filter-mapping>
<!-- 过滤器名称 -->
<filter-name>CountFilter</filter-name>
<!-- 过滤器URL映射 -->
<url-pattern>/index.jsp</url-pattern>
</filter-mapping>
注:1.中的可以是自定义名称,而中的需要与前者一 一对应。 2.在配置过滤器时,其URL映射可以使用正则表达式进行配置,如使用/*来匹配所有的请求。
完整案例:
实现一个图书信息录入的功能,并创建字符编码过滤器,避免中文乱码的产生。1.该过滤器可以对字符编码格式进行处理,解决中文乱码问题。
// 字符编码过滤器
public class CharactorFilter implements Filter {
// 字符编码
String encoding = null;
@Override
public void destroy() {
encoding = null;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 判断字符编码是否为空
if(encoding != null){
// 设置request的编码格式
request.setCharacterEncoding(encoding);
// 设置response字符编码
response.setContentType("text/html; charset="+encoding);
}
// 传递给下一过滤器
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 获取初始化参数
encoding = filterConfig.getInitParameter("encoding");
}
}
2.处理录入图书信息的servlet对象。
//添加图书信息的Servlet
public class AddServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
// 处理GET请求
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
// 处理POST请求
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取 PrintWriter
PrintWriter out = response.getWriter();
// 获取图书编号
String id = request.getParameter("id");
// 获取名称
String name = request.getParameter("name");
// 获取作者
String author = request.getParameter("author");
// 获取价格
String price = request.getParameter("price");
// 输出图书信息
out.print("<h2>图书信息添加成功</h2><hr>");
out.print("图书编号:" + id + "<br>");
out.print("图书名称:" + name + "<br>");
out.print("作者:" + author + "<br>");
out.print("价格:" + price + "<br>");
// 刷新流
out.flush();
// 关闭流
out.close();
}
}
3.servlet与servlet过滤器的配置。
<!-- 声明过滤器 -->
<filter>
<!-- 过滤器名称 -->
<filter-name>CharactorFilter</filter-name>
<!-- 过滤器的完整类名 -->
<filter-class>com.lyq.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映射 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 声明Servlet -->
<servlet>
<!-- Servlet名称 -->
<servlet-name>AddServlet</servlet-name>
<!-- Servlet完整类名 -->
<servlet-class>com.lyq.AddServlet</servlet-class>
</servlet>
<!-- Servlet映射 -->
<servlet-mapping>
<!-- Servlet名称 -->
<servlet-name>AddServlet</servlet-name>
<!-- URL映射 -->
<url-pattern>/AddServlet</url-pattern>
</servlet-mapping>
4.程序主界面,JSP页面。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>添加图书信息</title>
</head>
<body>
<form action="AddServlet" method="post">
<table align="center" border="1" width="350">
<tr>
<td class="2" align="center" colspan="2">
<h2>添加图书信息</h2>
</td>
</tr>
<tr>
<td align="right">图书编号:</td>
<td>
<input type="text" name="id">
</td>
</tr>
<tr>
<td align="right">图书名称:</td>
<td>
<input type="text" name="name">
</td>
</tr>
<tr>
<td align="right">作 者:</td>
<td>
<input type="text" name="author">
</td>
</tr>
<tr>
<td align="right">价 格:</td>
<td>
<input type="text" name="price">
</td>
</tr>
<tr>
<td class="2" align="center" colspan="2">
<input type="submit" value="添 加">
</td>
</tr>
</table>
</form>
</body>
</html>
servlet监听器
servlet监听器的作用是监听Web容器的有效期事件,因此,它是由容器管理的。利用Listener接口监听在容器中的某个执行程序,并且根据其应用程序的需求做出适当的响应。例如,在Web应用启动或关闭时执行一些任务(如数据库的链接或释放),或者想要监控session的创建和销毁,那么就可以通过监听器来实现。servlet监听器接近于Java的GUI程序的监听器,可以监听由Web应用中状态改变而引起的servlet容器产生的相应事件,然后接收并处理这些事件。
servlet上下文监听的创建与配置:
public class MyContentListener implements ServletContextListener {
//...
}
<listener>
<listener-class>完整包名加类名</listener-class>
</listener>