Java过滤器实现原理

来源:互联网 发布:mysql数据库设计案例 编辑:程序博客网 时间:2024/04/30 15:59

       过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上。过滤器可附加到一个或多个servlet或JSP页面上,并且可以检查进入这些资源的请求信息。在这之后,过滤器可以作如下的选择:

1.       以常规的方式调用资源(即,调用servlet或JSP页面)。

2.       利用修改过的请求信息调用资源。

3.       调用资源,但在发送响应到客户机前对其进行修改。

4.       阻止该资源调用,代之以转到其他的资源,返回一个特定的状态代码或生成替换输出。

        Filter 的基本功能是对Servlet容器调用Servlet的过程进行拦截,从而在Servlet进行响应处理的前后实现一些特殊的功能。

1、    在Servlet API 中定义了三个接口类来提供开发人员编写Filter程序:Filter,FIlterChain,FilterConfig

2、    Filter程序是一个实现了Filter接口的Java类,与Servlet程序相似,它由Servlet容器进行调用和执行

3、    Filter 程序需要在web.xml文件中进行注册和设置它所能拦截的资源:Filter程序可以拦截Jsp,Servlet,静态图片文件夹和静态html文件

 一   过滤器的原理:在Servlet作为过滤器使用时,它可以对客户的请求进行处理。处理完成后,他会交给下一个过滤器处理,这样,客户的请求在过滤器链里逐个处理,直到请求发送到目标为止。例如,某网站里有提交”修改的注册信息”的网页,当用户填写完修改信息并提交后,服务器在进行处理时需要做两项工作:

       判断客户端的会话是否有效;对提交的数据进行统一编码。这两项工作可以再由两个过滤器组成的过滤链里进行处理。当过滤器处理成功后,把提交的数据发送到最终目标;如果过滤器处理不成功,将把试图派发到指定的错误页面。在一个web应用程序中可以注册多个Filter程序,每个Filter程序都可以对一个或一组Servlet程序进行拦截。若有多个Filter程序组合成一个Filter链(过滤器链)。Filter链中各个Filter的拦截顺序与它们在应用程序的web.xml中映射的顺序一致。

       在基于 JSP 页面系统设计开发中,经常有一批页面需要对用户的身份进行验证,只有合法的用户才可以访问这些页面。显然可以在每个页面中添加身份验证,但这样做会给编程造成很大的麻烦,而且增加多余的代码。那么,如何解决JSP 页面用户身份验证呢?

二、JSP 页面中用户身份验证分析

 在有多个用户使用的 JSP 系统中,为了保障系统的隐秘性安全性,就需要对登录系统的用户进行身份验证以保证用户身份的合法性。一个用户首次登录系统后会在session

对象中留下它的标识[1],就可以利用这个标识来完成各个 JSP页面的用户身份验证。为了避免每个页面都进行身份验证而出现的麻烦,这里将通过Servlet 过滤器对JSP 页面统一进行身份验证。

三、用户身份验证的设计思路和技术要点

1、设计思路

 Servlet 过滤器验证用户是围绕 session 对象进行的。首先是实现用户登录的功能,在用户登录成功后产生一个session 标识;然后创建Servlet 过滤器,判断标识值是否正确,如果正确则通过验证,否则将给出提示信息并跳转到用户登录页面。

2、技术要点

 使用 Servlet 过滤器实现JSP 页面中用户身份验证,首先必须实现Filter 接口,且重写doFilter() 方法,由doFilter() 方法去处理过滤业务;其次,在web.xml 文件中配置Servlet 过滤器,指定过滤器的名称、过滤器包所在类的名称及过滤器的映射范围等 [2]。

四、JSP 页面中用户身份验证的实现

1、用户身份合法性确认 为了能够使用 Servlet 过滤器实现用户对 JSP 页面访问的合法性验证,首先需要根据用户登录号和密码等与数据库中的信息相比较,若能匹配成功,则是用户登录成功,就用session 对象存储该用户的标识;然后再由Servlet 过滤器实现对用户访问的各个页面的过滤。存储用户登录成功的session 标识的核心代码为:session.setAttribute("user",用户登录号 )。

 2、Servlet 过滤器的实现 

用 Servlet 过滤器实现用户身份验证的关键代码如下:

 package hzu.util.filters;

public class UserFilter extends HttpServlet implements Filter{

private FilterConfig filterConfig;

public void init(FilterConfig filterConfig)

throws ServletException{

this.filterConfig=filterConfig;

 }[NextPage]

public void doFilter(ServletRequest request,ServletResponse response, FilterChain chain) throws ServletException,IOException{

HttpSession session=((HttpServletRequest) request).getSession();

if(session.getAttribute(“user”)= =null){

PrintWriter out=response.getWriter();

out.print(“<script language=javascript>alert(„您还没登录, 请登录!!‟);javascript:location=‟系统登录的主页面 ';</script>");

out.flush();

out.close();

}

else{

chain.doFilter(request, response);

}

}

}

3、在web.xml 中配置Servlet 过滤器

在编写完Servlet过滤器后,要在web.xml文件中配置过滤器。也就是通过<filter></filter>标签指定Servlet过滤器的名称、过滤器包所在类的名称,通过<filter-mapping></filter-

mapping>标签配置Servlet 过滤器的映射路径

[3]。其关键代码如下:

 

<filter>

<filter-name>UserLoginFilter</filter-name>

<filter-class>hzu. util.filters.UserFilter</

filter-class>

</filter>

<filter-mapping>

<filter-name>UserLoginFilter</filter-name>

<url-pattern>

[/ 目录名 ]/*

</url-pattern>

<dispatcher>request</dispatcher>

<dispatcher>forward</dispatcher>

<dispatcher>include</dispatcher>

</filter-mapping>

 

java监听器  http://www.open-open.com/lib/view/open1350703815649.html

 

拦截器是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法
比如动态代理就是拦截器的简单实现,
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
Object result = null;

System.out.println("before invoke method :" + method.getName());

result = method.invoke(this.targetObj, args);

System.out.println("after invoke method : " + method.getName());

return result;
}
在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,
甚至在你抛出异常的时候做业务逻辑的操作。

过滤器是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符(聊天室经常用到的,一些骂人的话).