无拦截器
因为我们id是Long类型的会存在精度缺失,所以全局转换下
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
/**
* @author baoyuankai
*/
@Configuration
public class JacksonConfig {
/**
* Jackson全局转化long类型为String,解决jackson序列化时传入前端Long类型缺失精度问题
*/
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
Jackson2ObjectMapperBuilderCustomizer cunstomizer = new Jackson2ObjectMapperBuilderCustomizer() {
@Override
public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
//变成字符串
jacksonObjectMapperBuilder.serializerByType(Long.class, ToStringSerializer.instance);
}
};
return cunstomizer;
}
拦截器
/**
* 自定义请求头拦截器,将Header数据封装到线程变量中方便获取
* @author
*/
@Configuration
public class HeaderInterceptor implements AsyncHandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
SecurityContextHolder.setUserId(request.getHeader(SecurityConstants.USER_ID));
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
SecurityContextHolder.remove();
}
}
/**
*@Author:
*定义日志切面
*/
//@Component
//@Aspect
@Slf4j
public class WebLogAspect {
// 以 controller 包下定义的所有请求为切入点
@Pointcut("execution (* com.controllers..*.*(..))")
public void webLog() {
}
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
// 开始打印请求日志
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
// 打印请求相关参数
LogUtil.logApplicationInfo("========================================== Start ==========================================");
// 打印请求 userId
LogUtil.logApplicationInfo("请求userId : %s", request.getHeader(SecurityConstants.USER_ID));
// 打印请求 url
LogUtil.logApplicationInfo("请求地址 : %s", request.getRequestURL().toString());
// 打印 Http method
LogUtil.logApplicationInfo("请求方式 : %s", request.getMethod());
// 打印调用 controller 的全路径以及执行方法
LogUtil.logApplicationInfo("请求方法所在路径 : %s.%s", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer();
String[] keys = pnd.getParameterNames(method);
Object[] values = joinPoint.getArgs();
Map<String, Object> paramsMap = new HashMap<>();
if (values != null) {
for (int i = 0; i < values.length; i++) {
if (values[i] instanceof BindingResult ||
values[i] instanceof HttpServletRequest ||
values[i] instanceof HttpServletResponse ||
values[i] instanceof MultipartFile ||
values[i] instanceof MultipartFile[]) {
continue;
}
paramsMap.put(keys[i], values[i]);
}
}
// 打印请求入参
LogUtil.logApplicationInfo("请求参数 : %s", JSON.toJSONString(paramsMap));
}
@Around("webLog()")
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = proceedingJoinPoint.proceed();
// 打印出参
LogUtil.logApplicationInfo("响应参数 : %s", JSON.toJSONString(result));
// 执行耗时
LogUtil.logApplicationInfo("响应时间 : %s ms", System.currentTimeMillis() - startTime);
LogUtil.logApplicationInfo("=========================================== End ===========================================");
LogUtil.logApplicationInfo("");
return result;
}
@After("webLog()")
public void doAfter() throws Throwable {
// ThreadLocalUtil.clear();
// LogUtil.logApplicationInfo("=========================================== End ===========================================");
// 每个请求之间空一行
// LogUtil.logApplicationInfo("");
}
/**
* 拦截器配置
* @author
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private HeaderInterceptor headerInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//拦截路径可自行配置多个 可用 ,分隔开
InterceptorRegistration interceptorRegistration = registry.addInterceptor(headerInterceptor);
interceptorRegistration.addPathPatterns("/**"); // 需要拦截的路径
interceptorRegistration.excludePathPatterns( // 不拦截的路径
// 放行swagger相关的路径
"/swagger-ui/**",
"/swagger-resources/**",
"/v3/api-docs"
);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//配置拦截器访问静态资源
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/favicon.ico").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters){
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = converter.getObjectMapper();
// 生成JSON时,将所有Long转换成String
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
// // 时间格式化
// objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// objectMapper.setDateFormat(new SimpleDateFormat(DateUtil.PATTERN_TIME));
// 设置格式化内容
converter.setObjectMapper(objectMapper);
converters.add(0, converter);
}
// /**
// * 开启跨域
// */
// @Override
// public void addCorsMappings(CorsRegistry registry) {
// // 设置允许跨域的路由
// registry.addMapping("/**")
// // 设置允许跨域请求的域名
// .allowedOriginPatterns("*")
// // 是否允许证书(cookies)
// .allowCredentials(true)
// // 设置允许的方法
// .allowedMethods("*")
// // 跨域允许时间
// .maxAge(3600);
// }