You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot JWT非法Token异常处理:返回指定JSON响应需求

解决方案:捕获JWT格式异常并返回指定JSON响应

问题根源

你遇到的MalformedJwtException是在JWT认证Filter层抛出的,而非Controller层,所以单纯用@ExceptionHandler或JwtAuthenticationEntryPoint无法处理:

  • @ExceptionHandler仅能捕获Controller及后续流程抛出的异常
  • JwtAuthenticationEntryPoint只负责处理未认证场景(如无Token、Token过期但格式合法),不处理Token格式错误的情况

实现步骤

1. 在JWT认证Filter中捕获异常并返回响应

修改你的JWT Filter类,在校验Token时主动捕获MalformedJwtException,记录日志后手动写入指定JSON响应:

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private final JwtTokenProvider jwtTokenProvider;
    private final Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class);

    public JwtAuthenticationFilter(JwtTokenProvider jwtTokenProvider) {
        this.jwtTokenProvider = jwtTokenProvider;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String token = extractTokenFromRequest(request);
        try {
            if (token != null && jwtTokenProvider.validateToken(token)) {
                Authentication auth = jwtTokenProvider.getAuthentication(token);
                SecurityContextHolder.getContext().setAuthentication(auth);
            }
            filterChain.doFilter(request, response);
        } catch (MalformedJwtException ex) {
            // 记录完整异常日志到控制台
            logger.error("Invalid JWT token format detected", ex);
            // 返回指定JSON响应
            sendCustomErrorResponse(response, HttpStatus.BAD_REQUEST, "Unable to read JSON value");
        }
    }

    private String extractTokenFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }

    private void sendCustomErrorResponse(HttpServletResponse response, HttpStatus status, String message) throws IOException {
        response.setStatus(status.value());
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        new ObjectMapper().writeValue(response.getWriter(), Collections.singletonMap("data", message));
    }
}

2. 配置全局异常处理器兜底

为了覆盖Controller层可能出现的同类异常,添加全局异常处理器:

@ControllerAdvice
public class GlobalExceptionHandler {

    private final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(MalformedJwtException.class)
    public ResponseEntity<Map<String, String>> handleMalformedJwt(MalformedJwtException ex) {
        logger.error("Malformed JWT token encountered", ex);
        Map<String, String> response = Collections.singletonMap("data", "Unable to read JSON value");
        return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
    }
}

3. 确保Security配置正确

确认你的Security配置中已注册该Filter,且异常处理逻辑不冲突:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final JwtAuthenticationFilter jwtAuthFilter;
    private final JwtAuthenticationEntryPoint authEntryPoint;

    public SecurityConfig(JwtAuthenticationFilter jwtAuthFilter, JwtAuthenticationEntryPoint authEntryPoint) {
        this.jwtAuthFilter = jwtAuthFilter;
        this.authEntryPoint = authEntryPoint;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf(csrf -> csrf.disable())
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/Login").permitAll()
                        .anyRequest().authenticated()
                )
                .exceptionHandling(ex -> ex.authenticationEntryPoint(authEntryPoint))
                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }
}

验证效果

修改Token首字符调用/Hello接口时:

  • 控制台会打印完整的MalformedJwtException堆栈日志
  • 前端会收到响应:{"data":"Unable to read JSON value"}

内容的提问来源于stack exchange,提问作者Akash Kashid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 14:10:28