string boot 与 自定义interceptor的实例讲解
作者:Sniper_ZL 发布时间:2023-10-27 17:03:20
前面学习过过滤器, 但是过滤器是针对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 页面, 就会直接跳去登录页面.
来源:http://www.cnblogs.com/elvinle/archive/2017/12/23/8093062.html


猜你喜欢
- 1.C#是一种从C++和Java继承而来的,简单的,现代的,面向对象的语言.2.它的目标是综合Visual Basic高产和C++底层高效的
- 之前有学弟问过我一道java的面试题,题目不算难。用java实现杨辉三角。我花了点时间整理了一下,发现挺有意思的,于是想写下来分享一下。在写
- 1、定义方法的格式 访问修饰符 返回类型 方法名 (参数列表) { // 方法的主体… }2、静态方法在大多数时候,我们定义写一个方法,会把
- Java自定义动态数组1、静态数组向动态数组转变(1)静态数组,数组空间固定长度这个数组空间总长为4,如果此时新插入一个数据就会报数组空间不
- 本文实例讲述了C#操作ftp类。分享给大家供大家参考。具体如下:using System;using System.Collections.
- 前言在日常编码中,有了ide的支持,我们已经很少直接在命令行中直接执行java XXX命令去启动一个项目了。然而我们有没有想过,一个简单的j
- 本文实例讲述了Spring与Struts整合之让Spring管理控制器操作。分享给大家供大家参考,具体如下:一 Web配置<?xml
- 前言本篇开始讲解音频编辑的具体操作,从相对简单的音频裁剪开始。要进行音频裁剪,我的方案是开启一个Service服务用于音频裁剪的耗时操作,主
- SpringCloud 整合ribbon的时候出现了这个问题java.lang.IllegalStateException: No inst
- Feign调用中的两种Header传参方式在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,
- springboot 长轮询实现基于 @EnableAsync , @Sync@SpringBootApplication@EnableAs
- Collection 接口 :Collection是最基本的集合接口,声明了适用于JAVA集合(只包括Set和List)的通用方法。Set和
- 总结java里面关于获取当前时间的一些方法System.currentTimeMillis()获取标准时间可以通过System.curren
- C# 泛型(Generic)定义:泛型允许我们延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候。也就是说,泛型是可
- 引入为什么突然说一下Spring启动原理呢,因为之前面试的时候,回答的那可谓是坑坑洼洼,前前后后,补补贴贴。。。总而言之就是不行,再次看一下
- 新手当在一个类文件中进行了一些操作之后,会造成sout快捷命令无法自动生成。比如操作了import引入其它包之后。主要是对IDEA操作的不熟
- 本文介绍了Android轻松实现多语言的方法示例,分享给大家,具体如下:1.创建多语言包2.首先在onCreate方法中调用此方法查看上一次
- 0x001 算数运算符 int num1 = 1, num2 = 2; System.o
- 简介本文主要讲解如何用java Selenium 控制鼠标在浏览器上的操作方法。主要列举的代码示例,无图显示。可以自己上代码执行操作看效果。
- JAVA多线程断点下载原理如图:代码如下:import java.io.BufferedReader; import java.io.Fil