前面学习过过滤器,但是过滤器是针对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 举报,一经查实,本站将立刻删除。