一.環境
maven springboot版本2.x
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>
二.無效的攔截器代碼
自定義攔截器
/** * @author: Gabriel * @date: 2020/2/5 13:45 * @description 登錄認證攔截 */ @Slf4j @Component public class AuthenticationInterceptor implements HandlerInterceptor { @Autowired IUserService userService; /** * 前置處理-方法執行前執行 * @param request * @param response * @param handler * @return * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token = request.getHeader("token"); //如果不是映射到方法就放行 if (!(handler instanceof HandlerMethod)) { return true; } HandlerMethod handlerMethod = (HandlerMethod) handler; //獲取方法及其相關注解 //檢查是否有不需要登錄的注解,有則跳過認證 Method method = handlerMethod.getMethod(); if (method.isAnnotationPresent(NoRequiredLoginToken.class)) { NoRequiredLoginToken noRequiredLoginToken = method.getAnnotation(NoRequiredLoginToken.class); if (noRequiredLoginToken.required()) { return true; } } //檢查有沒有需要用戶權限的注解 if (method.isAnnotationPresent(RequiredLoginToken.class)) { RequiredLoginToken requiredLoginToken = method.getAnnotation(RequiredLoginToken.class); if (requiredLoginToken.required()) { //執行認證 if (StringUtils.isBlank(token)) { throw new BusinessException(ResultCode.NO_LOGIN); } //獲取token中的userId String userId; try { userId=JWT.decode(token).getAudience().get(0); } catch (JWTDecodeException e) { throw new BusinessException(ResultCode.NO_LOGIN); } User user = userService.getById(userId); if (ObjectUtil.isNull(user)) { //TODO 用戶不存在,請重新登錄,這里需要優化異常類的構造方法 throw new BusinessException(ResultCode.NO_LOGIN); } JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build(); try { jwtVerifier.verify(token); } catch (JWTVerificationException e) { //TODO 校驗失敗,token有誤 throw new BusinessException(ResultCode.NO_LOGIN); } return true; } } //未加注解的方法直接放行-默認是不需要校驗的 return true; } /** * 后置處理-方法執行后執行 * @param request * @param response * @param handler * @param modelAndView * @throws Exception */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } /** * 最終處理-控制器執行完成后執行 * @param request * @param response * @param handler * @param ex * @throws Exception */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
注冊攔截器
/** * @author: Gabriel * @date: 2020/2/5 14:15 * @description 登錄攔截配置 */ @Configuration @Order(1) public class InterceptorConfig implements WebMvcConfigurer { @Autowired private AuthenticationInterceptor authenticationInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authenticationInterceptor).addPathPatterns("/**"); } }
目的是攔截相關的接口,但是一直沒生效,最后發現是有其他的WebMvc相關配置沖突了,有其他的類繼承了 WebMvcConfigurationSupport,導致沖突
沖突的代碼
** * @author Gabriel * @date 2020-01-08 * @description 自定義SpringMvc轉換器 解決數據轉換問題(例如BigDecimal轉換為String,解決精度問題) */ @Configuration public class WebMvcConfig extends WebMvcConfigurationSupport { /** * Date格式化字符串 */ private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd"); /** * DateTime格式化字符串 */ private static final DateTimeFormatter DATETIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); /** * Time格式化字符串 */ private static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern("HH:mm:ss"); @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { super.configureMessageConverters(converters); final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); ObjectMapper objectMapper = converter.getObjectMapper(); // 反序列化失敗 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // long 轉換為字符串 SimpleModule simpleModule = new SimpleModule(); simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance); simpleModule.addSerializer(Long.class, ToStringSerializer.instance); simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); // 浮點型使用字符串 simpleModule.addSerializer(Double.class, ToStringSerializer.instance); simpleModule.addSerializer(Double.TYPE, ToStringSerializer.instance); simpleModule.addSerializer(BigDecimal.class, ToStringSerializer.instance); // java8 時間格式化 simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DATETIME_FORMAT)); simpleModule.addSerializer(LocalDate.class, new LocalDateSerializer(DATE_FORMAT)); simpleModule.addSerializer(LocalTime.class, new LocalTimeSerializer(TIME_FORMAT)); objectMapper.registerModule(simpleModule); // 為mapper注冊一個帶有SerializerModifier的Factory,處理null值 objectMapper.setSerializerFactory(objectMapper.getSerializerFactory() //CustomizeBeanSerializerModifier 自定義序列化修改器 .withSerializerModifier(new CustomizeBeanSerializerModifier())); // 處理中文亂碼問題 converter.setSupportedMediaTypes(ImmutableList.of(MediaType.APPLICATION_JSON_UTF8)); converter.setObjectMapper(objectMapper); converters.add(converter); converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8)); } }
解決方案:
去掉該配置即可,或者去掉@Configure注解,使該文件不生效