• 中文
    • English
  • 注册
  • 查看作者
  • 7:过滤器

    一.  过滤器简介

    Servlet 过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息。Servlet 过滤器是可用于 Servlet 编程的 Java 类,可以实现以下目的:

    在客户端的请求访问后端资源之前,拦截这些请求。

    在服务器的响应发送回客户端之前,处理这些响应。

    二.  使用过滤器

    首先创建对应的filter类,然后实现Filter接口,并实现Filter中的三个方法:

    package com.oaec.day07.filter;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    public class HelloFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            filterChain.doFilter(servletRequest,servletResponse);
        }
    
        @Override
        public void destroy() {
    
        }
    }

    其中,init的作用是在Web服务器启动时对Filter进行初始化,destroy的作用是在web服务器停止的时候回收某些资源,当一个 Filter 对象能够拦截访问请求时,Servlet 容器将调用 Filter 对象的 doFilter 方法。

    另外doFilter的参数中,FilterChain 用于定义一个 Filter 链的对象应该对外提供的方法,这个接口只定义了一个 doFilter 方法。

    doFilter 方法用于通知 Web 容器把请求交给 Filter 链中的下一个 Filter 去处理,如果当前调用此方法的 Filter 对象是Filter 链中的最后一个 Filter,那么将把请求交给目标 Servlet 程序去处理,它的作用我们可以理解将拦截的请求放行,然后继续执行之前的操作。在执行该方法之前的所有代码都是对用户请求进行预处理,而执行了该方法之后的代码都是对服务器响应进行后处理。

    三.  配置过滤器

    配置过滤器也有两种方法,可以在web.xml中配置,其中url-pattern中的/hello意为我们请求hello的时候,会用filter-class中的HelloFilter进行拦截。

    <filter>
        <filter-name>helloFilter</filter-name>
        <filter-class>com.oaec.day07.filter.HelloFilter</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>helloFilter</filter-name>
        <url-pattern>/hello</url-pattern>
        <url-pattern>/list</url-pattern>
        <url-pattern>/index.jsp</url-pattern>
        ……
    </filter-mapping>

    另外还可以使用注解配置,配置单个:

    @WebFilter(urlPatterns = "/hello")

    配置多个:

    @WebFilter(urlPatterns = {"/hello","/list","index.jsp",......})

    四.  例一

    假如我们有以下需求:有一个购物网站,如果用户在没有登录的情况下打开个人中心,则先让用户登录,登录成功后再自动跳转回个人中心。我们就可以使用过滤器来完成该操作。先来看一下如果不用ajax的代码:

    index.jsp:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
      <head>
        <title>$Title$</title>
      </head>
      <body>
      <h1>首页</h1>
      <c:if test="${sessionScope.username != null}">
        <p>欢迎:${sessionScope.username},<a href="${pageContext.request.contextPath}/logout">退出</a></p>
      </c:if>
      <c:if test="${sessionScope.username == null}">
        <p><a href="${pageContext.request.contextPath}/login.jsp">去登陆</a></p>
      </c:if>
      <ul>
        <li><a href="${pageContext.request.contextPath}/user.jsp">个人中心</a></li>
        <li><a href="${pageContext.request.contextPath}/order.jsp">我的订单</a></li>
        <li><a href="${pageContext.request.contextPath}/cart.jsp">购物车</a></li>
      </ul>
      </body>
    </html>

    user.jsp:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>个人中心</title>
    </head>
    <body>
    <h1>个人中心</h1>
    <p><a href="${pageContext.request.contextPath}/index.jsp">返回首页</a></p>
    </body>
    </html>

    login.jsp:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
    <head>
        <title>登录页面</title>
    </head>
    <body>
    <form action="${pageContext.request.contextPath}/login" method="post">
    <%--    只有通过传参来返回的时候,才需要下面的三行代码,如果url是null,说明是直接登录,而不是被跳转到登录--%>
        <c:if test="${param.url != null}">
            <input type="hidden" name="uri" value="${param.uri}">
        </c:if>
        <input type="text" name="username" placeholder="请输入用户名"> <br>
        <input type="password" name="password" placeholder="请输入密码"> <br>
        <input type="submit" value="登录">
    </form>
    </body>
    </html>

    login.jsp文件中,我们通过url输入框将获取到的url、用户名和密码提交。LogInFilter:

    package com.oaec.day09.filter;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    
    //@WebFilter(urlPatterns = "/hello")
    @WebFilter(urlPatterns = {"/hello","/hello.jsp","/user.jsp","/order.jsp","/cart.jsp"})
    public class LoginFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
        //方法一:将返回地址存入session
        /*@Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            HttpSession session = request.getSession();
            if(session.getAttribute("username") == null){
               //没有登录
                //获取请求地址
                String requestURI = request.getRequestURI();
                //讲请求地址存入session
                session.setAttribute("uri",requestURI);
                response.sendRedirect(request.getContextPath()+"/login.jsp");
            }else{
                //放行
                filterChain.doFilter(request,response);
            }
        }*/
    
        //方法二:将返回地址作为url参数返回
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("1");
    
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            HttpSession session = request.getSession();
            //如果等于null说明当前用户没有登录
            if(session.getAttribute("username") == null){
    
                //获取请求地址
                String requestURI = request.getRequestURI();
                StringBuffer requestURL = request.getRequestURL();
                response.sendRedirect(request.getContextPath()+"/login.jsp?uri="+requestURI);
            }else{
                //放行
                filterChain.doFilter(request,response);
                System.out.println("2");
            }
        }
    
        @Override
        public void destroy() {
    
        }
    }

    LogInServlet:

    package com.oaec.day09.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    
    @WebServlet("/login")
    public class LoginServlet extends HttpServlet {
    
        /*@Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String username = req.getParameter("username");
            String password = req.getParameter("password");
            if("admin".equals(username) && "123456".equals(password)){
                //登录成功
                HttpSession session = req.getSession();
                session.setAttribute("username",username);
                //返回被拦截的页面
                String uri = (String) session.getAttribute("uri");
                if(uri == null){
                    resp.sendRedirect(req.getContextPath()+"/index.jsp");
                }else {
                    resp.sendRedirect(uri);
                }
            }else{
                //登录失败
                resp.sendRedirect(req.getContextPath()+"/login.jsp");
            }
        }*/
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("3");
            String username = req.getParameter("username");
            String password = req.getParameter("password");
            String uri = req.getParameter("uri");
            if("admin".equals(username) && "123456".equals(password)){
                //登录成功
                HttpSession session = req.getSession();
                session.setAttribute("username",username);
                //返回被拦截的页面,如果uri是null或者是空,说明是直接打开登录页登录的
                if(uri == null || "".equals(uri)){
                    resp.sendRedirect(req.getContextPath()+"/index.jsp");
                }else {
                    //否则说明是打开a页面,但是因为没有登录而跳转到登录的,则跳转回到a页面
                    resp.sendRedirect(uri);
                }
            }else{
                //登录失败
                resp.sendRedirect(req.getContextPath()+"/login.jsp");
            }
        }
    }

    五.  例一执行过程

    首先,如果我们直接访问login.jsp,那么我们的请求参数中就没有uri这个参数,所以就不会进入下面的if

    <c:if test="${param.uri != null}">
            <input type="hidden" name="uri" value="${param.uri}">
        </c:if>

    在login.jsp中输入用户名和密码后,点击提交,便直接进入了Servlet:

    <form action="${pageContext.request.contextPath}/login" method="post">

    进入Servlet后,在doPost方法中,因为是直接登录,所以uri是null,进入if后直接重定向到主页了。

    if(uri == null || "".equals(uri)){
        resp.sendRedirect(req.getContextPath()+"/index.jsp");
    }else {
        //否则说明是打开a页面,但是因为没有登录而跳转到登录的,则跳转回到a页面
        resp.sendRedirect(uri);
    }

    接下来,如果我们在没有登录的情况下直接访问个人中心页(user.jsp),则会触发拦截器,进入LoginFilter,因为我们还没有登录,所以session.getAttribute(“username”)的值就是null,则进入下面的if,通过request.getRequestURI() 获取到请求的URL,并将其存入session后直接重定向到login.jsp进行登录,或者作为login.jsp的参数返回,这里后者为例

    if(session.getAttribute("username") == null){
    
        //获取请求地址
        String requestURI = request.getRequestURI();
        StringBuffer requestURL = request.getRequestURL();
        response.sendRedirect(request.getContextPath()+"/login.jsp?uri="+requestURI);

    重定向到login.jsp后,此时的url为:http://localhost:8888/day09/login.jsp?uri=/day09/user.jsp,所以这时login.jsp中的下面的if便会执行:

    <c:if test="${param.uri != null}">
            <input type="hidden" name="uri" value="${param.uri}">
        </c:if>

    输入用户名和密码后,点击登录,进入了Servlet,进入Servlet后,在doPost方法中,因为是不再是直接登录,所以uri是的值不再是null,则进入下面的else,直接重定向到user.jsp了

    if(uri == null || "".equals(uri)){
        resp.sendRedirect(req.getContextPath()+"/index.jsp");
    }else {
        //否则说明是打开a页面,但是因为没有登录而跳转到登录的,则跳转回到a页面
        resp.sendRedirect(uri);
    }

    六.  例二

    在上面的例子中,我们讲解了不使用Ajax的方式,接下来讲解一下使用Ajax的方式,并使用拦截器,还是先放出所有的代码:

    login.jsp

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>用户登录</title>
        <link rel="stylesheet" href="${pageContext.request.contextPath}/static/css/bootstrap.min.css"/>
        <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.min.js"></script>
        <script type="text/javascript">
            $(function () {
                $(":submit").click(function () {
                    //将表单序列化
                    var data = $("form").serialize();
                    //发起请求,完成登录
                    $.ajax({
                        url:"${pageContext.request.contextPath}/login",
                        type:"post",
                        data:data,
                        success:function (res) {
                            console.log(res);
                           if(res.result){
                                //成功,跳转到index.jsp
                               if(res.uri){
                                   location = res.uri;
                               }else{
                                   location = "${pageContext.request.contextPath}/index.jsp";
                               }
    
                            }else{
                                //失败
                                if(res.error === "密码错误"){
                                    $("input[name='password']").addClass("is-invalid");
                                    $("input[name='password']").next("p").addClass("text-danger").text(res.error);
                                }else if(res.error === "用户名不存在"){
                                    $("input[name='username']").addClass("is-invalid");
                                }
                            }
                        }
                    });
                    return false;
                });
            });
        </script>
    </head>
    <body class="container">
    <h1>用户登录</h1>
    <form role="form" action="${pageContext.request.contextPath}/login" method="post">
        <c:if test="${param.uri != null}">
            <input type="hidden" name="uri" value="${param.uri}">
        </c:if>
        <div class="form-group">
            <label for="username">用户名</label>
            <input type="text" class="form-control" name="username" id="username"
                   placeholder="请输入用户名">
            <p></p>
        </div>
        <div class="form-group">
            <label for="password">密码</label>
            <input type="password" class="form-control" name="password" id="password"
                   placeholder="请输入密码">
            <p></p>
        </div>
        <input class="btn btn-primary" type="submit" value="登录">
    </form>
    </body>
    </html>

    list.jsp:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
    <html>
    <head>
        <title>图书列表</title>
        <link rel="stylesheet" href="${pageContext.request.contextPath}/static/css/bootstrap.min.css"/>
        <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.8.3.min.js"></script>
        <script type="text/javascript">
            function del(e) {
                var result = confirm("确定删除吗?");
                if(result){
                    //找到要删除的tr
                    var tr = $(e).parent().parent();
                    //获取要删除的bookId
                    var bookId = tr.children(":first").text();
                    //请求删除
                    $.ajax({
                        url:"${pageContext.request.contextPath}/delete?bookId="+bookId,
                        type:"get",
                        success:function (res) {
                            /*console.log(res);
                            console.log(res.isLogin);
                            console.log(res.isLogin === false);*/
                            // return;
                            if(res.isLogin === false){
                                //没有登录
                                alert("请先登录")
                                location = "${pageContext.request.contextPath}/login.jsp";
                                return;
                            }
                            if(res.result){
                                //删除当前tr
                                tr.remove();
                                alert("删除成功!");
                            }else {
                                alert("删除失败!");
                            }
                        }
                    });
                }
            }
        </script>
    </head>
    <body class="container">
    <h1>图书列表</h1>
    <a href="${pageContext.request.contextPath}/form" class="btn btn-success mb-2">添加图书</a>
    <table class="table table-striped">
        <tr>
            <th>编号</th>
            <th>书名</th>
            <th>作者</th>
            <th>价格</th>
            <th>操作</th>
        </tr>
        <c:forEach items="${requestScope.books}" var="book">
            <tr>
                <td>${book.bookId}</td>
                <td>${book.name}</td>
                <td>${book.author}</td>
                <td><fmt:formatNumber value="${book.price}" type="currency"/> </td>
                <td>
                    <a class="btn btn-sm btn-primary" href="${pageContext.request.contextPath}/form?bookId=${book.bookId}">修改</a>
    <%--                <a class="btn btn-sm btn-danger" href="${pageContext.request.contextPath}/delete?bookId=${book.bookId}">删除</a>--%>
                    <a class="btn btn-sm btn-danger" href="javascript:void (0)" onclick="del(this)">删除</a>
                </td>
            </tr>
        </c:forEach>
    </table>
    </body>
    </html>

    LoginFilter.java :

    import com.alibaba.fastjson.JSON;
    import com.oaec.day08.util.HttpFilter;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.HashMap;
    import java.util.Map;
    
    @WebFilter(urlPatterns = {"/list", "/form", "/delete", "/saveOrUpdate"})
    public class LoginFilter extends HttpFilter {
    
        @Override
        public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
            HttpSession session = request.getSession();
            if (session.getAttribute("user") == null) {
                String requestURI = request.getRequestURI();
                //获取请求参数(查询字符串)
                String queryString = request.getQueryString();
                System.out.println("queryString = " + queryString);
                System.out.println("requestURI = " + requestURI);
    
                if (requestURI.endsWith("delete") || requestURI.endsWith("saveOrUpdate")) {
    //            if (isAjax(request)) {
                    //返回json字符串
                    response.setContentType("application/json;charset=utf-8");
                    PrintWriter writer = response.getWriter();
                    Map<String, Object> map = new HashMap<>();
                    map.put("isLogin", false);
                    writer.println(JSON.toJSONString(map));
                    writer.close();
    
                } else {
                    //没有登录,去登录
                    if(queryString != null){
                        requestURI += ("?" + queryString);
                    }
                    response.sendRedirect(request.getContextPath() + "/login.jsp?uri=" + requestURI);
                }
            } else {
                //已经登录,放行
                filterChain.doFilter(request, response);
            }
    
        }
    
    
    
    }

    DeleteServlet .java:

    import com.alibaba.fastjson.JSON;
    import com.oaec.day08.dao.BookDao;
    import com.oaec.day08.dao.impl.BookDaoImpl;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.HashMap;
    import java.util.Map;
    
    @WebServlet("/delete")
    public class DeleteServlet extends HttpServlet {
        private BookDao bookDao =new BookDaoImpl();
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            req.setCharacterEncoding("utf-8");
            String bid=req.getParameter("bookId");
            boolean b = bookDao.doDelete(Integer.parseInt(bid));
            resp.setContentType("application/json;charset=utf-8");
            PrintWriter writer = resp.getWriter();
            Map<String,Object> map = new HashMap<>();
            map.put("result",b);
            writer.println(JSON.toJSONString(map));
            writer.close();
            //        req.setAttribute("result",b);
    //        req.getRequestDispatcher("result.jsp").forward(req,resp);
        }
    }

    list.java

    import com.oaec.day08.dao.BookDao;
    import com.oaec.day08.dao.impl.BookDaoImpl;
    import com.oaec.day08.entity.Book;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.util.List;
    
    @WebServlet("/list")
    public class ListServlet extends HttpServlet {
        private BookDao bookDao = new BookDaoImpl();
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            List<Book> books = bookDao.queryAll();
            req.setAttribute("books",books);
            req.getRequestDispatcher("list.jsp").forward(req,resp);
    
        }
    }

    LoginServlet.java:

    import com.alibaba.fastjson.JSON;
    import com.oaec.day08.service.UserService;
    import com.oaec.day08.service.impl.UserServiceImpl;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.HashMap;
    import java.util.Map;
    
    @WebServlet("/login")
    public class LoginServlet extends HttpServlet {
    
        private UserService userService = new UserServiceImpl();
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //获取用户名和密码
            String username = req.getParameter("username");
            String password = req.getParameter("password");
            String uri = req.getParameter("uri");
            Map<String, Object> map = userService.login(username, password);
            Map<String,Object> json = new HashMap<>();
            if(map.containsKey("user")){
                //登录成功,将用户信息存入session
                req.getSession().setAttribute("user",map.get("user"));
                json.put("result",true);
                if(uri != null){
                    json.put("uri",uri);
                }
            }else{
                Object error = map.get("error");
                json.put("result",false);
                json.put("error",error);
            }
            resp.setContentType("application/json;charset=utf-8");
            PrintWriter writer = resp.getWriter();
            writer.println(JSON.toJSONString(json));
            writer.close();
        }
    
    }

    七. 例二执行过程

    接下来,我们从三个角度入手,分析上面的程序执行步骤:

    1.  直接访问login.jsp

    如果在没有登录的情况下,直接访问login.jsp,当我们点击登录按钮的时候,在该按钮的点击事件中通过return false阻止了表单提交,开始执行ajax方法,并通过serialize方法将表单序列化,因为是直接登录打开的login.jsp,uri中不带任何参数,所以form标签中的name为uri的输入框不会显示:

    <c:if test="${param.uri!= null}">
            <input type="hidden" name="uri" value="${param.uri}">
        </c:if>

    所以当ajax发起请求的时候,只有username和password两个输入框的内容被提交

    之后访问LoginServlet,如果用户名和密码正确,则进入下面的if,并将user的信息存入session,并将登录结果添加到json中,因为我们是直接登录,所以uri依旧还是null,则json.put(“uri”,uri) 并没有被执行。

     if(map.containsKey("user")){
                //登录成功,将用户信息存入session
                req.getSession().setAttribute("user",map.get("user"));
                json.put("result",true);
                if(uri != null){
                    json.put("uri",uri);
                }

    之后Servlet将json作为json字符串返回,回到login.jsp,如果登录成功,则进入login.jsp的ajax方法里的语句,因为我们是直接登录的,if(res.uri)的值是false,所以回到了index.jsp

    if(res.result){
         //登录成功,跳转到index.jsp
        if(res.uri){
            location = res.uri;
        }else{
            location = "${pageContext.request.contextPath}/index.jsp";
        }
    
     }else{

    2.  直接访问list

    如果在没有登录的情况下,直接访问list,首先访问list触发LoginFilter过滤器,接下来因为没有登录,则会进入LoginFilter的doFilter方法中的最外层的if,也就是:

    if (session.getAttribute("user") == null) {
    }

    此时通过getRequestURI()获取的值就是/xxx/list,不是以delete或者saveOrUpdate结尾,所以下面的if不成立,则进入其对应的else

    if (requestURI.endsWith("delete") || requestURI.endsWith("saveOrUpdate")) {
        .....
    } else {
    }

    又因为list不需要参数,所以queryString的值为null,所以下面的if依旧不成立

    if(queryString != null){

    所以执行response.sendRedirect直接重定向到login.jsp了,并将list的地址作为参数返回

    if (session.getAttribute("user") == null) {
        String requestURI = request.getRequestURI();
        //获取请求参数(查询字符串)
        String queryString = request.getQueryString();
        System.out.println("queryString = " + queryString);
        System.out.println("requestURI = " + requestURI);
        if (requestURI.endsWith("delete") || requestURI.endsWith("saveOrUpdate")) {
            //返回json字符串
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();
            Map<String, Object> map = new HashMap<>();
            map.put("isLogin", false);
            writer.println(JSON.toJSONString(map));
            writer.close();
        } else {
            //没有登录,去登录
            if(queryString != null){
                requestURI += ("?" + queryString);
            }
            response.sendRedirect(request.getContextPath() + "/login.jsp?uri=" + requestURI);
        }
    } else {

    此时再次打开login.jsp,重复之前的步骤,此时的login.jsp,已经有了uri这个参数,所以form标签中的name为uri的输入框会显示:

    <c:if test="${param.uri!= null}">
            <input type="hidden" name="uri" value="${param.uri}">
        </c:if>

    所以当ajax发起请求的时候,username和password和uri这三个输入框的内容都会被提交

    之后访问LoginServlet,登录结果,uri都会被添加到json中

     if(map.containsKey("user")){
                //登录成功,将用户信息存入session
                req.getSession().setAttribute("user",map.get("user"));
                json.put("result",true);
                if(uri != null){
                    json.put("uri",uri);
                }

    之后Servlet将json作为json字符串返回,回到login.jsp,如果登录成功,则进入login.jsp的ajax方法里的语句,因为我们是直接登录的,if(res.uri)的值不再是false,所以不再返回到index.jsp,而是返回了list

    if(res.result){
         //登录成功,跳转到index.jsp
        if(res.uri){
            location = res.uri;
        }else{
            location = "${pageContext.request.contextPath}/index.jsp";
        }
    
     }else{

    3.  通过ajax删除

    我们先来做以下操作,打开login.jsp,登录账号后,访问list,系统会通过ListServlet将页面转发到list.jsp,此时再另起一个窗口退出登录,再回到list页点击删除,程序会按照下面的步骤执行:

    首先通过点击删除后,会执行del函数,并执行del函数的ajax方法,并请求delete,此时会触发LoginFilter过滤器,因为没有登录,则会进入LoginFilter的doFilter方法中的最外层的if,也就是:

    if (session.getAttribute("user") == null) {
    }

    此时通过getRequestURI()获取的值就是/xxx/delete,所以进入下面的if,将imap作为JSON字符串输出

     if (requestURI.endsWith("delete") || requestURI.endsWith("saveOrUpdate")) {
                    //返回json字符串
                    response.setContentType("application/json;charset=utf-8");
                    PrintWriter writer = response.getWriter();
                    Map<String, Object> map = new HashMap<>();
                    map.put("isLogin", false);
                    writer.println(JSON.toJSONString(map));
                    writer.close();
    
                }

    回到list.jsp中的ajax方法,则会进入下面的if,跳转到登录页面

    if(res.isLogin === false){
        //没有登录
        alert("请先登录")
        location = "${pageContext.request.contextPath}/login.jsp";
        return;
    }

    此时的登录页面也是不带任何参数的,所以form标签中的name为uri的输入框不会显示:

    <c:if test="${param.uri!= null}">
            <input type="hidden" name="uri" value="${param.uri}">
        </c:if>

    所以当login.jsp的ajax发起请求的时候,只有username和password两个输入框的内容被提交

    之后访问LoginServlet,如果用户名和密码正确,则进入下面的if,并将user的信息存入session,并将登录结果添加到json中,因为我们是直接登录,所以uri依旧还是null,则json.put(“uri”,uri) 并没有被执行。

     if(map.containsKey("user")){
                //登录成功,将用户信息存入session
                req.getSession().setAttribute("user",map.get("user"));
                json.put("result",true);
                if(uri != null){
                    json.put("uri",uri);
                }

    之后Servlet将json作为json字符串返回,回到login.jsp,如果登录成功,则进入login.jsp的ajax方法里的语句,因为我们是直接登录的,if(res.uri)的值是false,所以回到了index.jsp

    if(res.result){
         //登录成功,跳转到index.jsp
        if(res.uri){
            location = res.uri;
        }else{
            location = "${pageContext.request.contextPath}/index.jsp";
        }
    
     }else{

    五.  Filter和Servlet的执行顺序

    如果访问被拦截的页面,那么先执行filter的doFilter中的FilterChain.chain.doFilter(request, response)之前的代码,然后执行servlet,然后回到filter执行chain.doFilter(request, response)后面的代码,以上面的例子为例,如果我们直接访问login.jsp,登录后控制台输出3,如果在没登录的情况下访问user.jsp,那么直接输出1,页面也会跳转到登录页,登录后,输出1和2。更加详细的执行顺序可以参考小楫轻舟丶前辈的解释:filter和servlet的执行顺序关系

    参考资料

    菜鸟教程

    山东省
  • 0
  • 0
  • 0
  • 2k
  • 请登录之后再进行评论

    登录
    单栏布局 侧栏位置: