Spring 拦截器(Interceptor)
🏷️ Spring Boot
1. 创建方法注解
创建一个名为 AllowAnonymousUser
的注解用以标记接口方法。
java
import java.lang.annotation.*;
/**
* 允许匿名用户访问
*
* @author jiajia
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface AllowAnonymousUser {
}
2. 创建拦截器
拦截器通过获取方法的注解以判断当前接口是否允许匿名用户访问。
java
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Objects;
/**
* 匿名用户拦截器
*
* @author jiajia
*/
@Component
@RequiredArgsConstructor
@Slf4j
@Order(900)
public class AllowAnonymousUserInterceptor extends HandlerInterceptorAdapter {
private final ObjectMapper objectMapper;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
if (isLogin()) {
return true;
}
if (!(handler instanceof HandlerMethod)) {
return false;
}
Method method = ((HandlerMethod) handler).getMethod();
// 存在该注解,即表示允许匿名用户访问
AllowAnonymousUser annotation = method.getAnnotation(AllowAnonymousUser.class);
boolean isAllow = !Objects.isNull(annotation);
if (!isAllow) {
fillResponse(response, ResponseCode.UN_LOGIN_USER_ERROR, "未登录用户不允许访问当前接口。");
}
return isAllow;
}
/**
* 填充响应
*
* @param response
* @param code
* @param msg
* @throws IOException
*/
private void fillResponse(HttpServletResponse response, Integer code, String msg) throws IOException {
// 校验失败返回前端
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = response.getWriter();
PublicResponse publicResponse = new PublicResponse();
publicResponse.setCode(code);
publicResponse.setMsg(msg);
out.append(objectMapper.writeValueAsString(publicResponse));
}
}
3. 注册拦截器
通过自定义 WebMvcConfigurer
接口的实现来注册拦截器。
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* Web MVC 配置
*
* @author jiajia
*/
@Configuration
public class MyWebMvcConfiguration implements WebMvcConfigurer {
@Autowired
private AllowAnonymousUserInterceptor allowAnonymousUserInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(allowAnonymousUserInterceptor)
.addPathPatterns("/**");
}
}
4. 标记接口
在接口的方法上添加 @AllowAnonymousUser
注解,即可将当前接口标记为匿名用户可访问。
同时也表示,其它未添加该注解的接口,匿名用户都是不可访问的。
java
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;
/**
* Test Controller
*
* @author jiajia
*/
@ApiIgnore
@Slf4j
@Validated
@RestController
@RequestMapping("test")
@RequiredArgsConstructor
public class TestController {
@AllowAnonymousUser
@GetMapping("hello")
public PublicResponse<String> sayHello() {
return new PublicResponse().data("Hello, World.");
}
}