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

SpringBoot Controller层测试抛出JSONException:无法解析JSON字符串

问题原因排查及解决方案

1. MockMvc初始化未关联全局异常处理器

如果你的@BeforeEach里用standaloneSetup手动构建MockMvc,但没注册@ControllerAdvice类,MockMvc无法识别全局异常处理器,返回的可能是默认错误页面(HTML)而非自定义JSON响应,自然会触发JSON解析失败。

  • 错误写法:
    @BeforeEach
    void setUp() {
        mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
    }
    
  • 修复方式:
    要么用webAppContextSetup加载完整Spring上下文,自动扫描@ControllerAdvice:
    @Autowired
    private WebApplicationContext webCtx;
    
    @BeforeEach
    void setUp() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webCtx).build();
    }
    
    要么手动给standaloneSetup添加全局异常处理器:
    @BeforeEach
    void setUp() {
        mockMvc = MockMvcBuilders.standaloneSetup(userController)
                            .setControllerAdvice(new GlobalExceptionHandler())
                            .build();
    }
    

2. ExceptionHandler返回的不是合法JSON

如果你的异常处理器直接返回字符串而非JSON结构,比如:

@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public String handleError() {
    return "参数非法";
}

服务器会返回纯文本,MockMvc尝试解析成JSON时必然报错。

  • 修正:返回带@ResponseBody的POJO或ResponseEntity:
@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ErrorResult handleError() {
    return new ErrorResult("参数非法");
}

3. MockMvc缺少自定义ObjectMapper配置

如果项目里自定义了ObjectMapper(比如配置日期格式、空值过滤),但手动初始化MockMvc时没指定该转换器,默认ObjectMapper可能无法正确序列化异常响应对象,生成无效JSON。

  • 修复:注入自定义ObjectMapper并配置到MockMvc:
@Autowired
private ObjectMapper customObjectMapper;

@BeforeEach
void setUp() {
    mockMvc = MockMvcBuilders.standaloneSetup(userController)
                          .setMessageConverters(new MappingJackson2HttpMessageConverter(customObjectMapper))
                          .build();
}

4. 测试请求未指定Accept头

如果测试时没加Accept: application/json,服务器可能返回text/html格式的默认错误页,而非JSON响应,导致解析失败。

  • 修复:在请求中添加Accept头:
mockMvc.perform(get("/users/{id}", -1)
               .accept(MediaType.APPLICATION_JSON))
       .andExpect(status().isBadRequest())
       .andExpect(jsonPath("$.msg").value("无效ID"));

5. 模拟的异常类型不匹配ExceptionHandler

如果Mockito模拟Service抛出的异常,不在你的ExceptionHandler处理范围内,Spring MVC会返回默认的错误页面(HTML),而非自定义JSON响应,自然无法解析成JSON。

  • 检查测试代码:确保模拟抛出的异常是ExceptionHandler声明处理的类型,比如:
// 确保这里抛出的IllegalArgumentException是处理器能处理的
when(userService.findById(-1)).thenThrow(new IllegalArgumentException("无效ID"));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 13:50:16