写一个简单食用的拦截器
写个Filter继承OncePerRequestFilter重写doFilterInternal
1、doFilterInternal方法
@WebFilter(filterName = "tenantAuthCheckFilter", urlPatterns = {"/v1/url/*"})
@Order(1)
public class TenantFilter extends OncePerRequestFilter {
@Autowired
private ServiceA serviceA;
@Autowired
private ExcludePathsConfig excludePathsConfig;
@Override
protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) throws ServletException, IOException {
String servletPath = request.getServletPath();
String userId = request.getHeader("userId");
if (!excludePathsConfig.getPaths().contains(servletPath)) {
User user = ServiceA.getProdInst(prodInstId);
if(user.getUserId!=userId){
throw new Exception("当前用户没权限");
}
}
filterChain.doFilter(request, response);
}
}
2、 将applicaiton.yml下的配置读取成List<String>
@Component
@ConfigurationProperties(prefix = "interceptorconfig.exclude")
@Data
public class ExcludePathsConfig {
private List<String> paths;
}
3、application.yml配置
interceptorconfig: # 拦截器配置
exclude:
paths:
- /v1/url/userList # 不拦截这个接口
- /v1/url/dict # 不拦截这个接口
4、启动类增加ServletComponentScan()
@ServletComponentScan(basePackages = {"cn.lihaiyu.test.*"})
5、Filter抛出错误方案
@RestController
public class ErrorController extends BasicErrorController {
public ErrorController() {
super(new DefaultErrorAttributes(), new ErrorProperties());
}
@RequestMapping(produces = {MediaType.APPLICATION_JSON_VALUE})
@Override
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
Map<String, Object> errorAttributes = getErrorAttributes(request, ErrorAttributeOptions.of(ErrorAttributeOptions.Include.EXCEPTION,ErrorAttributeOptions.Include.MESSAGE,ErrorAttributeOptions.Include.STACK_TRACE,ErrorAttributeOptions.Include.BINDING_ERRORS));
HttpStatus status = getStatus(request);
// 错误代码:-1
String code = String.valueOf(ErrorType.SYS_ERROR.getCode());
// 获取错误信息
String message = errorAttributes.get("message").toString();
ApiErrorResult apiErrorResult = new ApiErrorResult(code,message);
return new ResponseEntity<>(apiErrorResult,status);
}
}
public class ApiErrorResult extends LinkedHashMap<String,Object> {
private static final String CODE_KEY = "code";
private static final String MESSAGE_KEY = "message";
public ApiErrorResult(String code, String message) {
this.put(CODE_KEY,code);
this.put(MESSAGE_KEY,message);
}
}
6、需要注意的地方:
① 使用ServletComponentScan
SpringBootApplication 上使用@ServletComponentScan 注解后
Servlet可以直接通过@WebServlet注解自动注册
Filter可以直接通过@WebFilter注解自动注册
Listener可以直接通过@WebListener 注解自动注册
原文链接:https://blog.csdn.net/qq_35574640/article/details/87936672
② 不要在Filter上面使用@Component,否则 urlPatterns 失效,会拦截所有的请求
③ 抛出错误的方法,filter内无法直接抛出错误,需要借助 BasicErrorController