`

Java Web的过滤器简单介绍

阅读更多
之前分享了一篇别人写的文章,想想还是自己总结一下吧,加深记忆。

首先用一个图来展示直观的印象。




由图上我们可以看到只要是从客户端到达服务器的请求也好,或是从服务器端获得的响应到客户端,其实只要配置了过滤器,并且满足过滤器的拦截条件,那么过滤器中的逻辑处理等动作都会被执行。


过滤器是Java提供的一个接口,我们在编写一个过滤器的时候,需要实现这个接口,这个类中的三个方法将都会起作用。




一般我们的过滤逻辑都会在doFilter()方法中书写。


过滤器的生命周期和一般的Servlet其实都是一样的,有个差异就是,Servlet在执行的时候,时候有父类的service()方法分发下去分别执行对应的service()方法,最终执行我们的doGet()或者doPost()方法。但是Filter执行的是doFilter()
方法。




在整个web应用中,我们不光只会用到有个Filter,我们会有很多的过滤器,他们会组成一个过滤器链,就像是高速路的收费站一样,一个接一个的检查。但是在最后一个Filter的doFilter()方法执行完成之后,就会把对应拦截到的并且已经处理的请求发送的Web资源。




在编写Filter的时候,还会接受一些初始化参数,共我们调用,这些初始化的过程都是有java自己完成的,我们只需要做的就是我们给定一个参数名称和参数值,它自己会封装在一个FilterConfig对象中。这样的话,我们需要传递什么参数就可以在XML中配置了,不用再去改动class类。





写完过滤器了,但是WEB容器并不知道啊,因此现在就要像配置Servlet一样配置Filter了。





好了,现在就展示一些源码,看了源码大家就应该清楚了。

设置字符编码的过滤器

package i18n.filter;

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;
import javax.servlet.http.HttpServletRequest;

public class EncodingFilter implements Filter {

	private String enc = "GBK";

	@Override
	public void destroy() {
		System.out.println("EncodingFilter===》destroy");
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException {

		req.setCharacterEncoding(enc);

		HttpServletRequest request = (HttpServletRequest) req;

		System.out.println(request.getServletPath());

		chain.doFilter(req, res);

	}

	@Override
	public void init(FilterConfig cfg) throws ServletException {

		String encoding = cfg.getInitParameter("encoding");
		if (encoding != null) {
			this.enc = encoding;
		}

		System.out.println("EncodingFilter===》init");

	}

}


常用的检查用户是否登录的过滤器

package i18n.filter;

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;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Servlet Filter implementation class LoginCheckFilter
 */
public class LoginCheckFilter implements Filter {

    /**
     * Default constructor. 
     */
    public LoginCheckFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		System.out.println("LoginCheckFilter===》destroy");
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		
		HttpServletRequest req=
				(HttpServletRequest) request;
		HttpServletResponse res=
				(HttpServletResponse) response;
		
		
		HttpSession session=req.getSession();
		
		if(session.isNew()){
			res.sendRedirect(req.getContextPath()+"/index.jsp");
			return;
		}
		
		String path=req.getServletPath();
		Object userId=session.getAttribute("userId");
		if(userId!=null){
			chain.doFilter(request, response);
			return;
		}
		
		if("/index.jsp".equals(path)||
				"/login.do".equals(path)){
			chain.doFilter(request, response);
			return;
		}
		
		res.sendRedirect(req.getContextPath()+"/index.jsp");
		
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		System.out.println("LoginCheckFilter===》init");
	}

}


Servlet的代码

package i18n;

import java.io.IOException;

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

/**
 * Servlet implementation class LoginServlet
 */
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		this.doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		System.out.println("userId===" + request.getParameter("userId"));
		request.getSession().setAttribute("userId", "xxxxxxxx");
		request.setAttribute("errKey", "err.login.failure");
		request.getRequestDispatcher("/index.jsp").forward(request, response);
	}

}


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
	<display-name>i18n</display-name>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
	<servlet>
		<description></description>
		<display-name>LoginServlet</display-name>
		<servlet-name>LoginServlet</servlet-name>
		<servlet-class>i18n.LoginServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>LoginServlet</servlet-name>
		<url-pattern>/login.do</url-pattern>
	</servlet-mapping>

	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>i18n.filter.EncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>

	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<filter>
		<display-name>LoginCheckFilter</display-name>
		<filter-name>LoginCheckFilter</filter-name>
		<filter-class>i18n.filter.LoginCheckFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>LoginCheckFilter</filter-name>
		<url-pattern>*.jsp</url-pattern>
	</filter-mapping>
	<filter-mapping>
		<filter-name>LoginCheckFilter</filter-name>
		<url-pattern>*.do</url-pattern>
	</filter-mapping>

</web-app>



注意:

上述有多个过滤器,他们的启动顺序是按照xml文件中的配置顺序启动的,并且是在容器启动的时候初始化的,并不是第一次访问的时候启动的。

请求转发是不会再次经过过滤器的,因为他们是服务器端的跳转,并不是客户端向服务器端再次发起的。

重定向是会再次经过过滤器的,因为服务器会“引导”客户端浏览器重新向一个新的地址发送请求,那么肯定会再次经过过滤器。



总结:

过滤器是 Web 服务组件,可以访问客户端输入的请求和 Web 资源输出的响应

过滤器定义用于将过滤器名称与特定的类关联在一起

过滤器映射用于将过滤器映射至 Web 资源

Filter 接口包含各种方法,如 init()、doFilter() 和 destroy()

每次用户发送请求以及Web资源发送响应时都会调用 doFilter() 方法

FilterChain 接口用于调用过滤器链中的下一个过滤器

在初始化过程中,Servlet 使用 FilterConfig 将信息传递给过滤器

  • 大小: 57.9 KB
  • 大小: 52.7 KB
  • 大小: 23.9 KB
  • 大小: 72.8 KB
  • 大小: 49.4 KB
  • 大小: 59.5 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics