Java Web的过滤器简单介绍

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

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


[img]http://dl2.iteye.com/upload/attachment/0093/0552/06b57c5c-f6e5-3eb1-920f-f0ec4d1cbce6.jpg[/img]

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


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


[img]http://dl2.iteye.com/upload/attachment/0093/0554/4180a678-c79f-32e6-810f-a4d76e786cd2.jpg[/img]

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


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


[img]http://dl2.iteye.com/upload/attachment/0093/0556/c67c3a3c-825a-3b44-a802-e3b79c6bb663.jpg[/img]

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

[img]http://dl2.iteye.com/upload/attachment/0093/0558/9699850b-ad95-3fa9-9202-17ec568ca2a2.jpg[/img]


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


[img]http://dl2.iteye.com/upload/attachment/0093/0560/f7176906-03b5-3ca8-b72f-859d0c67ddfd.jpg[/img]


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


[img]http://dl2.iteye.com/upload/attachment/0093/0603/64c6d040-388b-30eb-98fd-2eaf89af8e78.jpg[/img]


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

[b]设置字符编码的过滤器[/b]

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");

}

}


常用的[b]检查用户是否登录的过滤器[/b]

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>



注意:

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

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

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


总结:

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

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

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

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

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

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

在初始化过程中,Servlet 使用 FilterConfig 将信息传递给过滤器[/b]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值