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

如何在Spring Test的RestTemplate中保留application/json头发送非JSON请求

解决RestTemplate发送非JSON文本时自动修改Content-Type的问题

要模拟Content-Type: application/json但请求体为非JSON乱码文本的测试场景,核心是绕过RestTemplate默认消息转换器的自动ContentType覆盖逻辑,以下是两种实用方案:

方案一:自定义StringHttpMessageConverter强制支持application/json

RestTemplate默认的StringHttpMessageConverter仅支持text/plain等媒体类型,当你设置Content-Type: application/json并发送字符串请求体时,它会自动替换为text/plain。我们可以自定义转换器,让它支持application/json类型:

@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MalformedJsonInputTest {

    @Autowired
    private TestRestTemplate testRestTemplate;

    @Test
    void testMalformedJsonRequest() {
        // 自定义String转换器,仅支持application/json
        StringHttpMessageConverter customConverter = new StringHttpMessageConverter();
        customConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));

        // 替换TestRestTemplate中的默认String转换器
        RestTemplate restTemplate = testRestTemplate.getRestTemplate();
        restTemplate.getMessageConverters().removeIf(c -> c instanceof StringHttpMessageConverter);
        restTemplate.getMessageConverters().add(customConverter);

        // 构造请求头与非JSON请求体
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        String malformedBody = "乱码或非JSON内容:@#$%^&*()_+";
        HttpEntity<String> request = new HttpEntity<>(malformedBody, headers);

        // 发送请求并验证响应
        ResponseEntity<String> response = restTemplate.exchange(
                "/api/your-target-endpoint",
                HttpMethod.POST,
                request,
                String.class
        );

        assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
    }
}

方案二:使用字节数组作为请求体绕开自动转换

直接将字符串转为字节数组,借助ByteArrayHttpMessageConverter发送请求——这个转换器不会修改你手动设置的Content-Type,完全尊重自定义请求头:

@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MalformedJsonInputTest {

    @Autowired
    private TestRestTemplate testRestTemplate;

    @Test
    void testMalformedJsonWithByteArray() {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        // 将非JSON文本转为字节数组
        String malformedBody = "非JSON乱码:!@#$%^&*";
        byte[] bodyBytes = malformedBody.getBytes(StandardCharsets.UTF_8);
        HttpEntity<byte[]> request = new HttpEntity<>(bodyBytes, headers);

        // 发送请求
        ResponseEntity<String> response = testRestTemplate.exchange(
                "/api/your-target-endpoint",
                HttpMethod.POST,
                request,
                String.class
        );

        assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
    }
}

关键原理

RestTemplate的消息转换器会根据请求体类型和配置的支持媒体类型自动调整Content-Type:

  • 默认StringHttpMessageConverter的支持列表不包含application/json,所以会强制替换为text/plain
  • 自定义转换器或使用字节数组,能避免这种自动替换,完全保留你设置的application/json请求头,完美模拟curl发送的非法Schema请求场景

内容的提问来源于stack exchange,提问作者e-info128

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 15:12:09