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

 更新时间:2017年12月23日 21:15:53   作者:Sniper_ZL  
下面小编就为大家分享一篇string boot 与 自定义interceptor的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

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

那这里来学习一下拦截器.

一. 拦截器的执行顺序

1. 目录

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 的时候, 就会在控制台输出响应的信息.

这样, 就能看出单个拦截器的执行顺序.

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 页面, 就会直接跳去登录页面.

以上这篇string boot 与 自定义interceptor的实例讲解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 基于SpringMVC拦截器实现接口耗时监控功能

    基于SpringMVC拦截器实现接口耗时监控功能

    本文呢主要介绍了基于SpringMVC拦截器实现的接口耗时监控功能,统计接口的耗时情况属于一个可以复用的功能点,因此这里直接使用 SpringMVC的HandlerInterceptor拦截器来实现,需要的朋友可以参考下
    2024-02-02
  • 实例详解Java调用第三方接口方法

    实例详解Java调用第三方接口方法

    很多项目都会封装规定好本身项目的接口规范,所以大多数需要去调用对方提供的接口或第三方接口(短信、天气等),下面这篇文章主要给大家介绍了关于Java调用第三方接口方法的相关资料,需要的朋友可以参考下
    2022-06-06
  • SpringBoot底层注解超详细介绍

    SpringBoot底层注解超详细介绍

    这篇文章主要介绍了SpringBoot底层注解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-09-09
  • Springboot实现页面间跳转功能

    Springboot实现页面间跳转功能

    这篇文章主要介绍了Springboot实现页面间跳转功能,本文给大家分享两种方式,方法一和方法二是不冲突的,但是通常情况下如果用方法二addViewControllers,需要把方法一所写的Controller类给注释掉,需要的朋友可以参考下
    2023-10-10
  • 使用Mybatis-plus实现时间自动填充(代码直接可用)

    使用Mybatis-plus实现时间自动填充(代码直接可用)

    这篇文章主要介绍了使用Mybatis-plus实现时间自动填充(代码直接可用),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • Java多线程之线程池七个参数详解

    Java多线程之线程池七个参数详解

    这篇文章主要介绍了Java多线程之线程池七个参数详解,文中有很详细的代码示例,对正在学习java的小伙伴们有很好的帮助,需要的朋友可以参考下
    2021-04-04
  • java统计字符串中指定元素出现次数方法

    java统计字符串中指定元素出现次数方法

    这篇文章主要介绍了java统计字符串中指定元素出现次数方法,需要的朋友可以参考下
    2015-12-12
  • 工作中禁止使用Executors快捷创建线程池原理详解

    工作中禁止使用Executors快捷创建线程池原理详解

    这篇文章主要为大家介绍了工作中禁止使用Executors快捷创建线程池原理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • JAVA获取文件绝对路径的方法

    JAVA获取文件绝对路径的方法

    这篇文章主要介绍了JAVA获取文件绝对路径的方法,涉及针对文件路径的操作技巧,需要的朋友可以参考下
    2015-02-02
  • Java泛型定义与用法实例详解

    Java泛型定义与用法实例详解

    这篇文章主要介绍了Java泛型定义与用法,结合实例形式较为详细的分析了Java中泛型的概念、原理、定义、使用方法及相关操作注意事项,需要的朋友可以参考下
    2018-08-08

最新评论