如何告诉RestTemplate使用UTF-8编码进行POST?

ans*_*ias 39 spring json resttemplate

我在使用RestTemplate发布带有UTF-8编码的JSON时遇到问题.JSON的默认编码是UTF-8,因此媒体类型甚至不应包含字符集.我试图将charset放在MediaType中,但它似乎无论如何都不起作用.

我的代码:

String dataJson = "{\"food\": \"smörrebröd\"}";
HttpHeaders headers = new HttpHeaders();
MediaType mediaType = new MediaType("application", "json", StandardCharsets.UTF_8);
headers.setContentType(mediaType);

HttpEntity<String> entity = new HttpEntity<String>(dataJson, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Boolean> formEntity = restTemplate.exchange(postUrl, HttpMethod.POST, entity, Boolean.class);
Run Code Online (Sandbox Code Playgroud)

mus*_*001 97

您需要使用charset UTF-8将StringHttpMessageConverter添加到模板的消息转换器中.像这样

RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters()
        .add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));
Run Code Online (Sandbox Code Playgroud)

  • 为什么是 `.add(0, ...` 而不仅仅是 `.add(new StringHttp...`? (3认同)
  • 像魅力一样工作。我遇到了一个特殊字符的问题,该字符看起来像是“(单引号)。解析时发生了一场噩梦。简单的调整值得一千张选票 (2认同)

Roh*_*hit 16

(添加到mushfek0001和zhouji的解决方案)

默认情况下,RestTemplate具有ISO-8859-1 StringHttpMessageConverter,用于将JAVA对象转换为请求有效负载.

UTF-8和ISO-8859之间的区别:

UTF-8是一种多字节编码,可以表示任何Unicode字符.ISO 8859-1是一个单字节编码,可以代表前256个Unicode字符.两者都以完全相同的方式编码ASCII.

解决方案1(从mushfek001复制):

RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters()
        .add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
Run Code Online (Sandbox Code Playgroud)

解决方案2:

虽然上面的解决方案有效,但正如周二指出的那样,它会添加两个字符串转换器,这可能会导致一些回归问题.

如果您在http标头中设置了正确的内容类型,那么ISO 8859将负责更改UTF字符.

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
Run Code Online (Sandbox Code Playgroud)

要么

// HttpUriRequest request
request.addHeader("Content-Type", MediaType.APPLICATION_JSON_UTF8_VALUE);
Run Code Online (Sandbox Code Playgroud)

  • MediaType.APPLICATION_JSON_UTF8_VALUE 现已弃用 (3认同)

zho*_*uji 6

通过@答案mushfek0001产生两个StringHttpMessageConverter将发送两个text/plain*/*,如调试画面.

在此输入图像描述

即使Accept是客户端的标题也是:

text/plain, text/plain, */*, */*
Run Code Online (Sandbox Code Playgroud)

所以更好的是删除 ISO-8859-1 StringHttpMessageConverter并使用单个UTF-8 StringHttpMessageConverter.

用这个:

RestTemplate restTemplate = new RestTemplate();
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
stringHttpMessageConverter.setWriteAcceptCharset(true);
for (int i = 0; i < restTemplate.getMessageConverters().size(); i++) {
    if (restTemplate.getMessageConverters().get(i) instanceof StringHttpMessageConverter) {
        restTemplate.getMessageConverters().remove(i);
        restTemplate.getMessageConverters().add(i, stringHttpMessageConverter);
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)