Servlet过滤器的使用

Servlet过滤器的使用

制作人:全心全意

Servlet过滤器:Servlet过滤器与Servlet十分相似,但它具有拦截客户端请求的功能,Servlet过滤器可以改变请求中的内容,来满足实际开发中的需要。对于程序开发人员而言,过滤器实质上就是在Web应用服务器上的一个Web应用组件,用于拦截客户端与目标资源的请求,并对这些请求进行一定过滤处理再发送给目标资源。

 

过滤器的核心对象

过滤器对象放置在javax.servlet包中,其名称为Filter,他是一个接口。除这个接口外,与过滤器相关的对象还有FilterConfig对象与FilterChain对象,这两个对象也同样是接口对象,位于javax.servlet包中,分别为过滤器的配置对象与过滤器的传递工具。在实际开发中,定义过滤器对象只需要直接或间接地实现Filter接口即可。Filter及相关对象结构图如下图所示。

  • Filter接口

 每一个过滤器对象都要直接或间接地实现Filter接口,在Filter接口中定义了3个方法,分别为init()方法,doFilter()方法和destroy()方法,其方法声明及说明如下表所示。

方  法  声  明 说     明
public void init(FilterConfig filterConfig) throws ServletException 过滤器的初始化方法,该方法在过滤器初始化时调用

public void doFilter(ServletReqest request,ServletResponse response,FilterChain chain)

  throws IOException,ServletException

对请求进行过滤处理
public void destroy() 销毁方法,释放资源

 

  • FilterConfig接口

 FilterConfig接口由Servlet容器进行实现,主要用于获取过滤器中的配置信息,其方法声明及说明如下表所示。

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

 

  • FilterChain接口

 FilterChain接口仍然由Servlet容器进行实现,在这个接口中只有一个方法,其方法声明及说明如下表所示。

方  法  声  明 说     明

public void doFilter(ServletRequest request,ServletResponse,response)

    throws IOException,ServletException

该方法用于将过滤后的请求传递给下一个过滤器,如果此过滤器已经是过滤链中的最后一个过滤器,

那么,请求将传递给目标资源

 

Servlet过滤器的代码结构

创建一个过滤器对象需要实现javax.servlet.Filter接口,同时实现Filter接口的3个方法。其代码结构如下。

 

package com.zq;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class MyFilter implements Filter {

	// 初始化方法
	public void init(FilterConfig fConfig) throws ServletException {
		// 初始化处理
	}

	// 过滤处理方法
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		// 过滤处理
		chain.doFilter(request, response);
	}

	// 销毁方法
	public void destroy() {
		// 释放资源
	}

}

过滤器中的init()方法用于对过滤器的初始化进行处理,destroy()方法是过滤器的销毁方法,主要用于释放资源,对于过滤处理的业务逻辑需要编写到doFilter()方法中,在请求过滤处理后,需要调用chain参数的doFilter()方法将请求向下传递给下一过滤器或目标资源。

 

Servlet过滤器的创建示例

实例1:网页访问计数

CountFilter类:过滤器对象,统计访问网站人数功能

package com.zq;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class NewFilter implements Filter {
	private int count;

	public void destroy() {

	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		count++;// 访问数量自增
		// 将ServletRequest转换成HttpServletRequest
		HttpServletRequest req = (HttpServletRequest) request;
		// 获取ServletContext

		ServletContext context = req.getSession().getServletContext();
		context.setAttribute("count", count); // 将来访数量值放入到ServletContext中
		chain.doFilter(request, response);// 向下传递过滤器
	}

	public void init(FilterConfig filterConfig) throws ServletException {
		String param = filterConfig.getInitParameter("count");
		count = Integer.valueOf(param);
	}

}

 

web.xml文件:Servlet过滤器对象声明、映射和设置初始化参数

	<filter>
		<filter-name>NewFilter</filter-name>
		<filter-class>com.zq.NewFilter</filter-class>
		<init-param>
			<param-name>count</param-name>
			<param-value>10</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>NewFilter</filter-name>
		<url-pattern>/index.jsp</url-pattern>
	</filter-mapping>

  

index.jsp页面:获取计数器的值

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>人数统计</title>
</head>
<body>
	<h2>
		欢迎光临,<br> 您是本站的第【
		<%=application.getAttribute("count")%>
		】位访客!
	</h2>
</body>
</html>

 

实例2:字符编码过滤器(图书信息添加预览)

在Java Web程序开发中,由于Web容器内部所使用的编码格式并不支持中文字符集,所以,处理浏览器请求中的中文数据就会出现乱码现象。在实际开发过程中,如果通过每一个业务处理指定字符集编码,则操作过于频繁,而且容易遗漏某一个业务中的字符编码设置;如果通过过滤器来处理字符编码,就可以做到简单又万无一失。

CharactorFilter类:过滤器对象,对请求中的字符编码格式进行设置。

package com.zq;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class CharactorFilter implements Filter {
	String encoding = null;

	public void destroy() {
		encoding = null;
	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		if (encoding != null) {// 判断字符编码是否为空
			request.setCharacterEncoding(encoding);// 设置request的编码格式
			response.setContentType("text/html;charset=" + encoding);// 设置response字符编码
		}
		chain.doFilter(request, response);
	}

	public void init(FilterConfig filterConfig) throws ServletException {
		encoding = filterConfig.getInitParameter("encoding");// 获取初始化参数

	}

}

CharactorFilter类是实例中的字符编码过滤器,它主要通过在doFilter()方法中,指定request与response两个参数的字符集encoding进行编码处理,使得目标资源的字符集支持中文。其中encoding是CharactorFilter类定义的字符编码格式成员变量,该变量在过滤器的初始化方法init()中被赋值,它的值是通过FilterConfig对象读取配置文件中的初始化参数获取的。

注意:在过滤器对象的doFilter()方法中,业务逻辑处理完成之后,需要通过FilterChain对象的doFilter()方法将请求传递到下一个过滤器或目标资源,否则将出现错误。

 

AddServlet类:处理添加图书信息请求的Servlet对象。

package com.zq;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class AddServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

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

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		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.println("<h2>图书信息添加成功</h2><hr>");
		out.println("图书编码:" + id + "<br>");
		out.println("图书名称:" + name + "<br>");
		out.println("图书作者:" + author + "<br>");
		out.println("图书价格:" + price + "<br>");
		out.flush();
		out.close();
	}

}

 AddServlet的类主要通过doPost()方法实现添加图书信息请求的处理,其处理方法是将所获取到的图书信息数据直接输出到页面中。

技巧:在Java Web程序开发中,通过情况下,Servlet所处理的请求类型都是GET或POST,所以可以在doGet()方法中调用doPost()方法,把业务处理代码写到doPost方法中,或在doPost()方法中调用doGet()方法,把业务处理代码写到doGet()方法中,无论Servlet接收的请求类型是GET还是POST,Servlet都对其进行处理。

 

web.xml文件:CharactorFilter类的Servlet过滤器的声明、映射和初始化参数;AddServlet类的Servlet对象的声明和映射

<filter>
	<filter-name>CharactorFilter</filter-name>
	<filter-class>com.zq.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>
<servlet>
	<servlet-name>AddServlet</servlet-name>
	<servlet-class>com.zq.AddServlet</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>AddServlet</servlet-name>
	<url-pattern>/AddServlet</url-pattern>
</servlet-mapping>

 

index.jsp页面:程序的主页,放置添加图书信息的表单。

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<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>

 

posted @ 2018-09-23 12:08  全心全意_运维  阅读(328)  评论(0编辑  收藏  举报