练涛

Servlet学习——@WebFilter注解方式使用过滤器

使用@WebFilter注解方式使用过滤器

学习前提:

  • 了解过滤器的web.xml中filter和filter-mapping的配置信息

过滤器的介绍:

Servlet3.0里面的过滤器跟以前版本的一样,还是需要实现javax.servlet.Filter接口
Filter接口中定义了三个方法,init()、destroy()和doFilter()(真正进行过滤处理的方法)。

方法介绍:

1 public void doFilter (ServletRequest, ServletResponse, FilterChain)
该方法完成实际的过滤操作,当客户端请求方法与过滤器设置匹配的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain用户访问后续过滤器。
2 public void init(FilterConfig filterConfig)
web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次)。开发人员通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。
3 public void destroy()
Servlet容器在销毁过滤器实例前调用该方法,在该方法中释放Servlet过滤器占用的资源。


Demo:

工具:myeclipse

Demo简介:

使用登陆小例子,不允许用户自行跳转到登陆成功的success.jsp页面,用过滤器拦截
并跳转回index.jsp页面。

代码:

LoginServlet.java

package servlet;

import java.io.IOException;

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


/**
 * Servlet implementation class LoginServlet
 */
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public LoginServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        //response.getWriter().append("Served at: ").append(request.getContextPath());
        doPost(request,response);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        //doGet(request, response);
        String username=request.getParameter("username");
        String password=request.getParameter("password");
        //判断输入的用户名和密码是不是都为admin
        if(username.equals("admin")&&password.equals("admin"))
        {
            //请求重定向
    request.getSession().setAttribute("username", username);
    response.sendRedirect(request.getContextPath()+"/login_success.jsp");
        }else
        {
            response.sendRedirect(request.getContextPath()+"/login_fail.jsp");
        }
    }

}

FilterTest.java

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

@WebFilter(filterName="FilterTest",urlPatterns="/login_success.jsp")
public class FilterTest implements Filter {

    @Override
    public void destroy() {
        System.out.println("过滤器destroy方法执行~");
    }

    @Override
    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
            throws IOException, ServletException {
        System.out.println("Start……doFilter");
         HttpServletRequest request = (HttpServletRequest) arg0;
         HttpServletResponse response = (HttpServletResponse) arg1;
         HttpSession session = request.getSession();
        //arg2.doFilter(arg0, arg1);

         //如果是login.jsp,则不拦截,直接放行,不用进行其他操作
         if(request.getRequestURI().indexOf("index.jsp")!=-1 ){
                   arg2.doFilter(arg0, arg1);
                   return;
                  }
        //因为登录后保存了username,所以可以先检查username判断是否登录
        if(session.getAttribute("username")!=null){
                      arg2.doFilter(arg0, arg1);//已登录,则放行,
                  }else{
                      response.sendRedirect("login_fail.jsp");//未登录,重定向到登录页面
                  }
      //如果是下面3个url,则不拦截,直接放行,不用进行其他操作
        if(request.getRequestURI().indexOf("index.jsp")!=-1 
         ||request.getRequestURI().indexOf("/LoginServlet")!=-1 
         ||request.getRequestURI().indexOf("login_fail.jsp")!=-1 )
        {
                     arg2.doFilter(arg0, arg1);
                     return;
         }
        System.out.println("End……doFilter");
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        System.out.println("过滤器init()执行了~");
    }

}

index.jsp

<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

//在index.jsp页面输出文字测试 doFilter()的方法执行顺序
System.out.println("here is index.jsp ");

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>FilterTest</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->
  </head>

  <body>
     <h1>使用@WebFilter注解的过滤器测试页面</h1><br><hr>
      <form action="<%=request.getContextPath() %>/LoginServlet" method="post">
        用户名:<input type="text" name="username">
         密码:<input type="password" name="password">
            <input type="submit" value="提交"> 
     </form>
  </body>
</html>

success.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>登陆成功</title>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>

  <body>
    <h1>登陆成功!</h1> <br>
  </body>
</html>

fail.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>My JSP 'login_fail.jsp' starting page</title>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>

  <body>
    <h1>登陆失败!</h1>
    <a href="index.jsp">返回登陆</a> 
    <br>
  </body>
</html>

过程:

创建FliterTest.java时使它继承Fliter接口,然后myclipese会生成需要重写的三个方法,在该类声明的上面一行输入:@WebFilter(filterName=”FilterTest”,urlPatterns=”/login_success.jsp”)
其他步骤没有什么重点,略过
启动tomcat,可以看到init()执行了:
init
然后,地址栏输入项目地址访问项目index.jsp页面(localhost:8080/ServletFliter/index.jsp),后台也输出:here is index.jsp。
输入用户名、密码(都是admin),可以访问到,login_success.jsp页面。后台却并没有什么输出,这是因为,我们并没有出发到过滤器。
接着,我们触发一下过滤器,看看他的工作顺序。在地址栏输入localhost:8080/ServletFliter/login_success.jsp(我们的初衷就是让用户不能这样访问).
于是结果为:
result
如图,我们发现后台输出了:Start和End 说明我们的过滤器中的doFilter方法已经执行了,而且经过了逻辑判断,最后重定向到了index.jsp页面。

Ps:可以选着跳转到失败页面来确定,过滤器是否真的工作了。另外,建议先测试login_success.jsp是否被拦截,再验证用户密码是否能正确登陆,因为,session在tomcat里默认时长为30分钟,会导致一直是登陆成功状态。

posted @ 2018-03-10 15:01  练涛  阅读(1978)  评论(0编辑  收藏  举报