string boot 与 自定义interceptor的实例讲解

作者:Sniper_ZL 时间:2023-10-27 17:03:20 

前面学习过过滤器, 但是过滤器是针对servlet的, 用在springmvc和spring boot里面, 功能上, 感觉并不是很好用.

那这里来学习一下 * .

一. * 的执行顺序

1. 目录

string boot 与 自定义interceptor的实例讲解

2. *

* 里面, 我加了三个(First,Two,Third), 但是内容都差不多.


package org.elvin.boot.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FirstInterceptor implements HandlerInterceptor {
 @Override
 public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
   System.out.println("FirstInterceptor preHandle");
   return true;
 }
 @Override
 public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
   System.out.println("FirstInterceptor postHandle");
 }
 @Override
 public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
   System.out.println("FirstInterceptor afterCompletion");
 }
}

preHandle 返回true, 才会继续下面的执行.

* 注册:


package org.elvin.boot.interceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class RegisterInterceptor extends WebMvcConfigurerAdapter {
 @Override
 public void addInterceptors(InterceptorRegistry registry) {
   registry.addInterceptor(new FirstInterceptor());
   registry.addInterceptor(new TwoInterceptor());
   registry.addInterceptor(new ThirdInterceptor());
   super.addInterceptors(registry);
 }
}

为了验证执行顺序, 这里使用了 thymeleaf, 然后在前台访问了我后台传过去的属性, 在访问的时候, 就会打印信息到控制台


package org.elvin.boot.pojo;
public class Book {
 private String name ;
 public String getName() {
   System.out.println("view : Book'name is " + name);
   return name;
 }
 public void setName(String name) {
   this.name = name;
 }
}

Controller:


package org.elvin.boot.Controller;
import org.elvin.boot.pojo.Book;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("first")
public class FirstController {
 private String controllerPath = "first/";
 @GetMapping("index")
 public String index(Model model){
   System.out.println("controller : FirstController index doing...");
   Book book = new Book();
   book.setName("spring boot");
   model.addAttribute("book", book);
   return controllerPath + "index";
 }
}

View:


<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8" />
 <title>Title</title>
</head>
<body>
 <h1 th:text="${book.name}"></h1>
</body>
</html>

在访问 localhost:8080/first/index 的时候, 就会在控制台输出响应的信息.

string boot 与 自定义interceptor的实例讲解

这样, 就能看出单个 * 的执行顺序.

1. 在控制器方法执行之前, 执行的 preHandle 方法

2. 执行控制器的action方法

3. 执行完action, 解析view之前(如果有的话), 执行 * 的 posthandle 方法

4. 解析view

5. 解析完之后, 执行 afterCompletion 方法

当注册多个 * 的时候, 执行顺序, 如图上所示了.

二. * 实现权限验证

同样的, 先加入权限 *


package org.elvin.boot.interceptor;
import org.elvin.boot.annotation.NoLogin;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginInterceptor implements HandlerInterceptor {
 @Override
 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handle) throws Exception {
   HandlerMethod method = (HandlerMethod ) handle;
   Class<?> controllerType = method.getBeanType();
   if(method.getMethodAnnotation(NoLogin.class) != null || controllerType.getAnnotation(NoLogin.class) != null){
     return true;
   }
   HttpSession session = request.getSession();
   String token = (String)session.getAttribute("token");
   if(!StringUtils.isEmpty(token)){
     return true;
   }
   response.sendRedirect("/login/index");
   return false;
 }
 @Override
 public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
 }
 @Override
 public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
 }
}

然后注册权限 *


package org.elvin.boot.interceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class RegisterInterceptor extends WebMvcConfigurerAdapter {
 @Override
 public void addInterceptors(InterceptorRegistry registry) {
   registry.addInterceptor(new LoginInterceptor());
   super.addInterceptors(registry);
 }
}

在控制器中加入登录控制器, 提供登录页面和注销方法


package org.elvin.boot.Controller;
import org.elvin.boot.annotation.NoLogin;
import org.springframework.beans.factory.annotation.Autowired;
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 org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@NoLogin
@Controller
@RequestMapping("login")
public class LoginController {
 @Autowired
 private HttpServletRequest request;
 @Autowired
 private HttpServletResponse response;
 private String controllerPath = "login/";
 //@NoLogin
 @GetMapping("index")
 public String index(){
   HttpSession session = request.getSession();
   session.setAttribute("token", "token");
   return controllerPath + "index";
 }
 //@NoLogin
 @PostMapping("checkOut")
 @ResponseBody
 public String checkOut(){
   HttpSession session = request.getSession();
   session.setAttribute("token", null);
   return "ok";
 }
}

这里我做了一个免登录注解, 可以加在Controller上, 也可以加在 action 上.


package org.elvin.boot.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NoLogin {
}

注解里面, 并不需要任何内容.

登录页面(这里登录页面只是为了注销用的, 所以访问过这个页面之后, 就表示登录成功了).


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
 <meta charset="UTF-8"/>
 <title>Title</title>
</head>
<body>
<div class="container">
 <input type="button" value="注销" id="checkOut"/>
</div>

<script th:src="@{/js/jquery-1.11.1.js}"></script>
<script th:inline="javascript">
 $(function () {
   $(".container").delegate("#checkOut", "click", function () {
     $.ajax({
       url: [[@{/login/checkOut}]],
       type: 'post',
       data: {},
       success: function (res) {
         if (res == "ok") {
           alert("注销成功");
         }
       }
     });
   });
 });
</script>
</body>
</html>

结果演示方式:

在浏览器中, 先打开 http://localhost:8080/login/index 页面, 然后在新标签中访问 http://localhost:8080/first/index 页面.

你会发现访问 first/index 的时候, 是可以访问的.

此时, 在login/index页面中, 点击注销按钮之后, 再刷新 first/index 页面, 就会直接跳去登录页面.

来源:http://www.cnblogs.com/elvinle/archive/2017/12/23/8093062.html

标签:string,boot,自定义,interceptor
0
投稿

猜你喜欢

  • Java毕业设计实战之医院心理咨询问诊系统的实现

    2022-07-04 19:02:21
  • Java日常练习题,每天进步一点点(42)

    2022-10-28 01:42:54
  • C# List<T>的用法小结

    2021-12-03 10:40:28
  • java日期工具类实例分享

    2023-05-17 17:50:40
  • Android ActionBar完全解析使用官方推荐的最佳导航栏(下)

    2022-04-27 02:35:03
  • Java锁之可重入锁介绍

    2021-06-01 03:05:19
  • android layout 按比例布局的代码

    2022-10-11 13:02:40
  • C语言 OutputDebugString与格式化输出函数OutputDebugPrintf案例详解

    2023-11-02 16:21:47
  • Java多线程工具CompletableFuture的使用教程

    2023-07-30 20:31:45
  • Java移动文件夹及其所有子文件与子文件夹

    2023-08-01 09:53:38
  • 简单掌握Linux系统中fork()函数创建子进程的用法

    2023-03-15 20:40:20
  • Android Fragment实现底部通知栏

    2023-12-25 21:01:33
  • 详解Java面试官最爱问的volatile关键字

    2021-10-10 01:55:33
  • Java实现从Html文本中提取纯文本的方法

    2023-06-18 20:28:26
  • C#多线程基础知识汇总

    2023-03-06 08:35:47
  • C#中32位浮点数Float(Real)一步步按位Bit进行分析

    2023-07-19 16:01:20
  • SpringBoot集成Beetl后统一处理页面异常的方法

    2023-11-10 19:57:55
  • Android常用的数据加密方式代码详解

    2022-07-24 14:30:06
  • Spring AOP面向切面编程实现原理方法详解

    2021-07-22 00:26:07
  • dubbo将异常转换成RuntimeException的原因分析 ExceptionFilter

    2023-11-24 14:25:13
  • asp之家 软件编程 m.aspxhome.com