加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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

发布时间:2020-12-14 20:14:21 所属栏目:Java 来源:网络整理
导读:前面学习过过滤器,但是过滤器是针对servlet的,用在springmvc和spring boot里面,功能上,感觉并不是很好用. 那这里来学习一下拦截器. 一. 拦截器的执行顺序 1. 目录 2. 拦截器 拦截器里面,我加了三个(First,Two,Third),但是内容都差不多. package org.elvin.bo

前面学习过过滤器,但是过滤器是针对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,Object o,ModelAndView modelAndView) throws Exception {
    System.out.println("FirstInterceptor postHandle");
  }
  @Override
  public void afterCompletion(HttpServletRequest httpServletRequest,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,ModelAndView modelAndView) throws Exception {
  }
  @Override
  public void afterCompletion(HttpServletRequest httpServletRequest,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的实例讲解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持编程小技巧。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读