一、拦截器简介
在Spring Boot项目中,拦截器(Interceptor)是指在控制器(Controller)方法处理请求之前或之后执行一些逻辑的特殊类。拦截器可以用于实现功能如日志记录、权限验证、参数校验、事务管理等。 在Spring Boot中,拦截器通常是通过注解@ControllerAdvice或@Around来定义的。@ControllerAdvice用于定义全局的异常处理和拦截器逻辑,而@Around则可以精细控制拦截器的执行顺序和逻辑。 拦截器在处理请求时,可以在控制器方法调用之前或之后执行一些逻辑,例如记录日志、验证用户权限、处理异常等。通过使用拦截器,可以将一些重复的逻辑提取出来,减少代码的冗余,提高代码的可维护性和可扩展性。
二、拦截器和过滤器的区别
在Spring Boot项目中,拦截器(Interceptor)和过滤器(Filter)都是用于在请求处理过程中执行一些额外的逻辑,但它们之间还是有一些区别的:
1. 拦截器是Spring框架特有的概念,而过滤器是Java Servlet框架中的概念。
2. 拦截器可以访问被拦截的方法的参数和返回值,并且可以在方法调用前和调用后执行自己的逻辑。而过滤器只能访问请求和响应的上下文对象,并且只能在请求处理前和处理后执行自己的逻辑。
3. 拦截器的应用场景更加广泛,可以用于实现AOP编程、权限控制、数据验证等功能。而过滤器的应用场景相对较小,主要用于实现日志记录、性能统计等功能。
4. 在Spring Boot中,拦截器的使用更加方便,通过注解方式即可实
现拦截器的配置和使用。而过滤器的使用相对较为繁琐,需要在web.xml配置文件中进行配置。 综上所述,拦截器和过滤器都有各自的应用场景和优缺点,在选择使用时需要根据具体的需求进行评估。如果需要实现的功能比较复杂或者需要与Spring框架集成更加紧密的逻辑,建议使用拦截器;如果需要实现的功能比较简单且不涉及AOP编程等高级逻辑,可以考虑使用过滤器。
三、拦截器的配置
package com.sky.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "sky.jwt")//自动装配
@Data
public class JwtProperties {
/**
* 管理端员工生成jwt令牌相关配置
*/
private String adminSecretKey;
private long adminTtl;
private String adminTokenName;
/**
* 用户端微信用户生成jwt令牌相关配置
*/
private String userSecretKey;
private long userTtl;
private String userTokenName;
}
1、新建一个拦截器
package com.sky.interceptor;
import com.sky.constant.JwtClaimsConstant;
import com.sky.context.BaseContext;
import com.sky.properties.JwtProperties;
import com.sky.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* jwt令牌校验的拦截器
*/
@Component
@Slf4j
public class JwtTokenAdminInterceptor implements HandlerInterceptor {
@Autowired
private JwtProperties jwtProperties;
/**
* 校验jwt
*
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//判断当前拦截到的是Controller的方法还是其他资源
if (!(handler instanceof HandlerMethod)) {
//当前拦截到的不是动态方法,直接放行
return true;
}
//1、从请求头中获取令牌
String token = request.getHeader(jwtProperties.getAdminTokenName());
//2、校验令牌
try {
log.info("jwt校验:{}", token);
Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);
Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());
log.info("当前员工id:", empId);
BaseContext.setCurrentId(empId);
//3、通过,放行
return true;
} catch (Exception ex) {
//4、不通过,响应401状态码
response.setStatus(401);
return false;
}
}
}
2、配置拦截器
package com.sky.config;
import com.sky.interceptor.JwtTokenAdminInterceptor;
import com.sky.interceptor.JwtTokenUserInterceptor;
import com.sky.json.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.cbor.MappingJackson2CborHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import java.util.List;
/**
* 配置类,注册web层相关组件
*/
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
@Autowired
private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;
@Autowired
private JwtTokenUserInterceptor jwtTokenUserInterceptor;
/**
* 注册自定义拦截器
*
* @param registry
*/
protected void addInterceptors(InterceptorRegistry registry) {
log.info("开始注册自定义拦截器...");
registry.addInterceptor(jwtTokenAdminInterceptor)
.addPathPatterns("/admin/**")
.excludePathPatterns("/admin/employee/login");
}
}