Filter的原理与使用(对用户进行统一验证)

一、Filter原理

    过滤器,顾名思义就是在源数据和目的数据之间起过滤作用的中间组件。当Web容器接收到一个对资源的请求时,它将判断是否有过滤器与这个资源相关联,如果有,那么容器将把请求交给过滤器进行处理。在过滤器中,你可以改变请求的内容,或者重新设置请求的报头信息,然后再将请求发送给目标资源。当目标资源对请求作出响应时,容器同样会将响应先转发给过滤器,在容器中,你可以对响应的内容进行转换,然后再将响应发送到客户端。

    在Web应用程序中部署过滤器,对客户端和目标资源来说是透明的。

二、Filter使用(对用户进行统一验证)

1. 编写登陆页面logon.jsp

<%@ page contentType="text/html;charset=GB2312" %>
<form method="post" action="logon.jsp?action=logon">
    <table>
        <tr><td>用户名:</td><td><input type="text" name="name"></td></tr>
        <tr><td>密码:</td><td><input type="password" name="password"></td></tr>
        <tr><input type="hidden" name="origin_uri" value="${requestScope.origin_uri}"></tr><!--保存用户先前访问的页面-->
        <tr><td><input type="reset" value="重填"></td><td><input type="submit" value="提交"></td></tr>
    </table>
</form>

2. 编写过滤器类

package test;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class LogonFilter implements Filter
{
    private static final String LOGON_URI="logon_uri";
    private static final String HOME_URI="home_uri";
    private String logon_page;    
    private String home_page;
    
    public void init(FilterConfig filterConfig) throws ServletException{   
        //从部署描述符中获取登录页面和首页的URI。
        logon_page=filterConfig.getInitParameter(LOGON_URI);
        home_page=filterConfig.getInitParameter(HOME_URI);
        if(null==logon_page || null==home_page)
            throw new ServletException("没有指定登录页面或主页!");
    }
   
    public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws IOException, ServletException{
        //将请求对象和响应对象的类型转换为HttpServletRequest和HttpServletResponse。
        HttpServletRequest httpReq=(HttpServletRequest)request;
        HttpServletResponse httpResp=(HttpServletResponse)response;
        HttpSession session=httpReq.getSession();
        
        //得到用户的请求URI。
        String request_uri=httpReq.getRequestURI();
        //得到Web应用程序的上下文路径。
        String ctxPath=httpReq.getContextPath();
        //去除上下文路径,得到剩余部分的路径。
        String uri=request_uri.substring(ctxPath.length());
        
        //判断用户访问的是否是登录页面
        if(logon_page.equals(uri)){
            //如果是登录页面,则通过查看是否有附加的请求参数,来判断用户是访问登录页面,还是提交登录信息。
            String strLogon=httpReq.getParameter("action");
            if("logon".equals(strLogon)){
                //如果是提交登录信息,则对用户进行验证。
                String name=httpReq.getParameter("name");
                String password=httpReq.getParameter("password");
                if("zhangsan".equals(name) && "1234".equals(password)){
                    //验证通过后,在Session对象中设置isLogon属性为true。
                    session.setAttribute("isLogon","true");
                    //在Session对象中保存用户名。
                    session.setAttribute("user",name);
                    //从请求对象中取出用户先前访问页面的URI。
                    String origin_uri=httpReq.getParameter("origin_uri");
                    //如果origin_uri不为空,则将客户端重定向到用户先前访问的页面,否则将客户端重定向到首页。
                    if(null!=origin_uri && !"".equals(origin_uri)){
                        httpResp.sendRedirect(origin_uri);
                    }else{
                        httpResp.sendRedirect(ctxPath+home_page);
                    }
                    return;
                }else{
                    //如果验证失败,则从请求对象中获取用户先前访问页面的URI。
                    //如果该URI存在,则再次将它作为origin_uri属性的值保存到请求对象中。
                    String origin_uri=httpReq.getParameter("origin_uri");
                    if(null!=origin_uri && !"".equals(origin_uri)){
                        httpReq.setAttribute("origin_uri",origin_uri);
                    }
                    httpResp.setContentType("text/html;charset=GB2312");
                    PrintWriter out=httpResp.getWriter();
                    out.println("<h2>用户名或密码错误,请重新输入。</h2>");
                    RequestDispatcher rd=httpReq.getRequestDispatcher(logon_page);
                    rd.include(httpReq,httpResp);
                    return;
                }
            }else{
                //如果用户不是提交登录信息,则调用chain.doFilter()方法,调用目标资源(登录页面)。
                chain.doFilter(request, response);
                return;
            }
        }else{   
            //如果访问的不是登录页面,则判断用户是否已经登录。
            String isLogon=(String)session.getAttribute("isLogon");
            if("true".equals(isLogon)){
               chain.doFilter(request, response);
               return;
            }else{
                //如果用户没有登录,则将用户的请求URI作为origin_uri属性的值保存到请求对象中。
                String strQuery=httpReq.getQueryString();
                if(null!=strQuery){
                    request_uri=request_uri+"?"+strQuery;
                }
                httpReq.setAttribute("origin_uri",request_uri);
                
                //将用户请求转发给登录页面。
                RequestDispatcher rd=httpReq.getRequestDispatcher(logon_page);
                rd.forward(httpReq,httpResp);
                return;
            }
        }
    }
    
    public void destroy(){}
}

3. 编写首页页面home.jsp

//当用户直接访问首页时将跳转到登陆页面

<%@ page contentType="text/html;charset=gb2312" %>
${sessionScope.user},欢迎你。

4. 部署过滤器

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
 
  <filter>
        <filter-name>LogonFilter</filter-name>
        <filter-class>test.LogonFilter</filter-class>

        <!-- 设定登陆页面和首页 -->
        <init-param>
            <param-name>logon_uri</param-name>
            <param-value>/logon.jsp</param-value>
        </init-param>
        <init-param>
            <param-name>home_uri</param-name>
            <param-value>/home.jsp</param-value>
        </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>LogonFilter</filter-name>
        <url-pattern>/*</url-pattern><!--访问该Web应用下的任何内容都会调用此Filter-->
    </filter-mapping>
</web-app>




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值