软件编程
位置:首页>> 软件编程>> java编程>> string boot 与 自定义interceptor的实例讲解

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

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

标签:string,boot,自定义,interceptor

前面学习过过滤器, 但是过滤器是针对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

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com