SpringMvc学习笔记(十一)拦截器专题

拦截器就是过滤器的一种, 拦截器有且只能拦截Controller层(Servlet) ,本文实现一个登录拦截器,没有登录就不能访问登录之后的页面。

源码获取github

1.项目结构

2.拦截器

Java Web阶段学习过滤器

  • 实现javax.servlet.Filter接口
  • 过滤器是在服务器启动的时候就对齐进行实例化操作,如果你的过滤器错误,那么服务将无法启动,所以整个程序无法运行
    • init 初始化数据
    • doFilter(ServletRequest req , ServletResponse resp, ChainFilter chain)
    • 强制类型转换 HttpServletRequest request = (HttpServletRequest)req;
    • 关键的代码 chain.doFilter(req,resp);
      • 访问下一个过滤器或者资源
    • destroy 服务器关闭

在web.xml中配置

<filter>
    <filter-name>
    <filter-class>
    <init-param>
</filter>
<filter-mapping>
    <url-patterns>过滤的路径,我们自己可以设置规则 *.jsp *.html /*</url-patterns>
    <servlet-name>servlet过滤器名字</servlet-name>
</filter-mapping>

拦截器 : 理解为 拦截器就是过滤器的一种, 拦截器有且只能拦截Controller层(Servlet) @Controller的注解层次

3.如何建立拦截器

1.新建一个类

MyInterceptor.java

package com.hs.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
///一般情况下,我们只是关心preHandle方法即可
public class MyInterceptor implements HandlerInterceptor {
   @Override
   public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
      System.out.println("preHandle:访问Controller之前执行");
//    return false;   //阻止访问下一个
      return true;    //访问下一个拦截器或资源
   }

   @Override
   public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
      System.out.println("postHandle:访问到正确的视图之前");
   }

   @Override
   public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
      System.out.println("afterCompletion:JSP页面加载完毕之后执行");
   }
}

2.配置文件

在springmvc.xml中加入

<!--7.配置自定义的拦截器-->
<mvc:interceptors>
  <!--下面这个可以有多个-->
   <mvc:interceptor>
      <!--拦截的路径,类似url-patterns-->
      <mvc:mapping path="/sys/**"/>
      <mvc:mapping path="/vip/**"/>
      <!--排除路径,以下路径不经过拦截器处理-->
      <mvc:exclude-mapping path="/vip/test02/"/>
      <!--使用哪个拦截器处理-->
      <bean class="com.hs.interceptor.MyInterceptor"/>
   </mvc:interceptor>
</mvc:interceptors>

3.新建controller

DemoController.java

package com.hs.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class DemoController {

   @GetMapping("/sys/test01")
   public String test01() {
      System.out.println("Controller层test01方法");
      return "jsp/result01";
   }

   @GetMapping("/vip/test02")
   public String test02() {
      System.out.println("Controller层test02方法");
      return "jsp/result02";
   }

}

4.页面代码

result01.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>Title</title>
</head>
<body>
<% System.out.println("JSP-result01页面");%>
<h2>resulet01.jsp</h2>
</body>
</html>

result02.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>Title</title>
</head>
<body>
<% System.out.println("JSP-result02页面");%>
<h2>resulet02.jsp</h2>
</body>
</html>

测试,在浏览器网址栏依次输入/sys/test01,/vip/test02,查看控制台输出

4.实现一个登录拦截器

配置springmvc.xml
<!--登录设置的拦截器-->
<mvc:interceptor>
   <mvc:mapping path="/sys/**"/>
   <mvc:exclude-mapping path="/sys/login"/>
   <bean class="com.hs.interceptor.LoginInterceptor"/>
</mvc:interceptor>
LoginController.java
package com.hs.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("/sys")
public class LoginController {

   /**
    * 在地址栏输入/sys/login 进行请求转发跳转页面
    *
    * @return
    */
   @GetMapping("/login")
   public String login() {
      return "jsp/login";
   }

   /**
    * 表单提交验证,存入session
    *
    * @param account
    * @param request
    * @return
    */
   @PostMapping("/login")
   public String login(String account,HttpServletRequest request){
      System.out.println(account);
      HttpSession session  = request.getSession();
      if("admin".equals(account)){
         session.setAttribute("session_user", account);
         //redirect重定向跳到另外一个controller里
         return "redirect:/sys/main";
      }
      return "jsp/login";
   }

   /**
    * 登录成功重定向到这个controller,然后这个controller请求转发到一个页面
    * @return
    */
   @GetMapping("/main")
   public String main(){
      return "jsp/result01";
   }
}
login.jsp
<form action="login" method="post">
   <input type="text" name="account">
   <button>登录</button>
</form>

这里有一个很大的坑,自己纠结了很久,action的路径问题!!!

如果写sys/login是绝对路径,login相对路径,因为请求转发到login.jsp,但是网址栏还是在sys这层,表单提交要到login那个,要不然就用相对路径,要不然就是绝对路径,相对直接login就行,绝对路径就是要这样写

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
   //项目的发布路径,例如:  /rabc
   String path = request.getContextPath();
   /*
   全路径,形式如下: http://127.0.0.1:8001/rbac/
   request.getScheme()      ——> http 获取协议
   request.getServerName()  --> 127.0.0.1 获取服务名
   request.getServerPort()  --> 8001 获取端口号
   path                     --> /rbac 获取访问的路径 路
   */
   String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%--
   <base/>标签解决路径问题
   参考文章:http://www.cnblogs.com/muqianying/archive/2012/03/16/2400280.html
--%>
<!DOCTYPE HTML>
<html>
<head>
   <base href="<%=basePath%>">
   <meta charset="UTF-8">
   <title></title>
</head>
<body>
<h2>登录</h2>
<%--action的路径问题,sys/login绝对路径,login相对路径,因为请求转发到login.jsp,但是网址栏还是在sys这层,表单提交要到login那个,要不然就用相对路径,要不然就是绝对路径,相对直接login就行,绝对就是这样上面那一大堆--%>
<form action="sys/login" method="post">
   <input type="text" name="account">
   <button>登录</button>
</form>
</body>
</html>
LoginInterceptor.java,登录拦截器
package com.hs.interceptor;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.PrintWriter;

/**
 * 登录拦截器
 */
public class LoginInterceptor extends HandlerInterceptorAdapter {
   @Override
   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      //1.获取HttpSession
      HttpSession session = request.getSession();
      //2.判断是否登录
      if (session.getAttribute("session_user") == null) {
         //3.防止浏览器的后退功能
         response.setContentType("text/html;charset=UTF-8");
         PrintWriter out = response.getWriter();

         out.write("<script>");
         out.write("alert('您还没有登录过该系统,请登录!!!');");
         out.write("window.top.location.href='"+request.getContextPath()+"/sys/login'");
         out.write("</script>");

         out.flush();
         out.close();
         return false;
      }
      return true;
   }
}
发布了44 篇原创文章 · 获赞 31 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_39707130/article/details/81940822