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

Spring Boot 3.5.0 Rest Controller路径变量空返回400 HTML响应问题

解决Spring Boot 3.5.0中空路径变量返回自定义JSON响应的问题

为啥之前的方案无效

当请求路径是/v1/users//jobs这类包含空路径变量的格式时,Spring MVC能匹配到对应的控制器映射,只是在路径变量绑定或参数校验阶段抛出异常,根本不会触发NoHandlerFoundException——这就是你之前针对该异常的处理完全没用的原因。默认情况下Spring Boot会把这类异常转换成HTML格式的400响应,而非你想要的自定义JSON。

可行解决方案

1. 捕获正确的异常类型

在@ControllerAdvice类里,针对实际抛出的异常编写处理器,主要关注以下几种:

  • ConstraintViolationException:控制器类加了@Validated后,@NotNull这类校验注解触发时抛出
  • ServletRequestBindingException:路径变量绑定失败时抛出(包含MissingPathVariableException子类)
  • InvalidPathVariableException:路径变量格式无效时抛出

示例代码:

import jakarta.validation.ConstraintViolationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
public class GlobalExceptionHandler {

    // 处理参数校验异常(比如@NotNull触发的空路径变量)
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseEntity<Map<String, Object>> handleConstraintViolation(ConstraintViolationException e) {
        Map<String, Object> response = new HashMap<>();
        response.put("code", HttpStatus.BAD_REQUEST.value());
        response.put("message", "路径变量不能为空");
        response.put("details", e.getMessage());
        return ResponseEntity.badRequest().body(response);
    }

    // 处理路径绑定相关的异常
    @ExceptionHandler({ServletRequestBindingException.class, InvalidPathVariableException.class})
    public ResponseEntity<Map<String, Object>> handlePathVariableErrors(Exception e) {
        Map<String, Object> response = new HashMap<>();
        response.put("code", HttpStatus.BAD_REQUEST.value());
        response.put("message", "请求路径格式无效,请检查路径变量");
        response.put("details", e.getMessage());
        return ResponseEntity.badRequest().body(response);
    }
}

2. 配置Spring Boot默认返回JSON

在配置文件中添加以下配置,确保异常场景下优先返回JSON而非HTML:
如果是application.yml:

spring:
  mvc:
    problemdetails:
      enabled: true  # 启用标准问题详情格式,默认返回JSON
  web:
    resources:
      add-mappings: false  # 禁用静态资源映射,避免跳转到HTML错误页

如果是application.properties:

spring.mvc.problemdetails.enabled=true
spring.web.resources.add-mappings=false

3. 验证效果

重启服务后,执行测试请求:

curl http://localhost:8080/v1/users//jobs -H 'requestId: b4c0-a6ddc4807cf1'

就能得到类似这样的自定义JSON响应:

{
  "code": 400,
  "message": "路径变量不能为空",
  "details": "update.userId: 不能为null"
}

注意事项

  • 控制器类上的@Validated不能丢:这是触发@NotNull等校验注解的前提,没加的话空路径变量不会触发ConstraintViolationException。
  • 别再盯着NoHandlerFoundException:这个异常只有当请求路径完全找不到任何控制器映射时才会抛,和空路径变量的场景完全不搭。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 08:03:13