zoukankan      html  css  js  c++  java
  • 【SpringMVC配置失效】Springboot2.x拦截器配置不无生效

    一.环境

      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注解,使该文件不生效

      

  • 相关阅读:
    Mac10.12下Python3.4调用oracle
    java或Jmeter实现两个日期相加减(2003-06-01-2003-05-01)
    Jmeter使用JDBC请求简介
    草火论
    学习五有
    中国特色的信息技术实践中的两种思路:信息索引化和信息持久化
    软件工程基本原理
    东亚文化原理
    临死之前我要写一本《中国哲学史——以自然主义和人道主义的矛盾为视角》
    总体软件观五个规律
  • 原文地址:https://www.cnblogs.com/july-sunny/p/12266719.html
Copyright © 2011-2022 走看看