• 中文
    • English
  • 注册
  • 赞助本站

    • 支付宝
    • 微信
    • QQ

    感谢一直支持本站的所有人!

    • 查看作者
    • 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
    • 733
    • 请登录之后再进行评论

      登录
    • 做任务
    • 实时动态
    • 偏好设置
    • 返回顶部
    • 单栏布局 侧栏位置: