一. 过滤器简介
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的执行顺序关系
请登录之后再进行评论