Spring Boot 的拦截器使用非常方便,我们只需要以下两步:
- 自定义类实现
HandlerInterceptor并注解@Component让Spring管理;- 自定义一个配置类实现
WebMvcConfigurer,注解@Configuration让Spring当作配置类管理;
有时候我们需要对控制器的某个方法进行匿名访问可以通过自定义一个注解,例如@AnonymousAccess ,然后在拦截器对该注解直接放行,可实现方法匿名访问。
HandlerInterceptor总共有三个方法:
- preHandler()方法是在对资源的请求之前调用;
- postHandler()方法是对资源的请求之后且在渲染视图之前;
- afterCompletion()方法是在渲染视图之后的回调,所以我们可以根据业务需求在合适的方法里增加自己的业务代码;
对于资源的拦截配置有注释说明,直接上代码:
1.权限拦截器:
package com.example.demo.interceptor;
import com.example.demo.annotation.AnonymousAccess;
import org.springframework.stereotype.Component;
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;
/**
* 权限拦截器
*/
@Component
public class SecurityInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (handler instanceof HandlerMethod) {
HandlerMethod method = (HandlerMethod) handler;
AnonymousAccess anonymousAccess = method.getMethodAnnotation(AnonymousAccess.class);
// 如果访问的方法上有AnonymousAccess注解,则匿名访问不拦截
if (anonymousAccess != null) {
return true;
}
}
String requestURI = request.getRequestURI();
// 对指定的路径放行
if (!"/api/v1/user/info".equals(requestURI)) {
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
2.配置拦截器:
package com.example.demo.config;
import com.example.demo.interceptor.SecurityInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 拦截器配置类
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
private final SecurityInterceptor securityInterceptor;
@Autowired
public InterceptorConfig(SecurityInterceptor securityInterceptor) {
this.securityInterceptor = securityInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration interceptorRegistration = registry.addInterceptor(securityInterceptor);
//配置拦截器忽略的路径
interceptorRegistration.excludePathPatterns("/api/v1/signup");
}
}
3.匿名访问注解:
package com.example.demo.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 匿名访问
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnonymousAccess {
}
4.用户模型:
package com.example.demo.module;
/**
* 用户模型
*/
public class User {
private String name;
private String phone;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", phone='" + phone + '\'' +
'}';
}
}
5.控制器:
package com.example.demo.controller;
import com.example.demo.module.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/v1/user")
public class UserController {
@GetMapping("/info")
// @AnonymousAccess
public User info() {
User user = new User();
user.setName("张三");
user.setPhone("110");
return user;
}
}
6.启动程序:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}