微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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,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的实例讲解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持编程小技巧。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐