Json 如何告诉RestTemplate使用UTF-8编码发布?

Json 如何告诉RestTemplate使用UTF-8编码发布?,json,spring,resttemplate,Json,Spring,Resttemplate,我在使用RestTemplate发布带有UTF-8编码的JSON时遇到问题。JSON的默认编码是UTF-8,因此媒体类型甚至不应该包含字符集。我曾尝试将字符集放入MediaType中,但它似乎无论如何都不起作用 我的代码: String dataJson = "{\"food\": \"smörrebröd\"}"; HttpHeaders headers = new HttpHeaders(); MediaType mediaType = new MediaType("application"

我在使用RestTemplate发布带有UTF-8编码的JSON时遇到问题。JSON的默认编码是UTF-8,因此媒体类型甚至不应该包含字符集。我曾尝试将字符集放入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);
String dataJson=“{\'food\”:\'smörrebröd\”;
HttpHeaders=新的HttpHeaders();
MediaType MediaType=新的MediaType(“应用程序”,“json”,StandardCharsets.UTF_8);
headers.setContentType(mediaType);
HttpEntity=新的HttpEntity(dataJson,标头);
RestTemplate RestTemplate=新RestTemplate();
ResponseEntity formEntity=restTemplate.exchange(postrl,HttpMethod.POST,entity,Boolean.class);

您需要使用字符集UTF-8将StringHttpMessageConverter添加到rest模板的消息转换器。像这样

RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters()
        .add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));

添加新的StringHttpMessageConverter不会有帮助。 在现有的StringHttpMessageConverter中,我们需要将writeAcceptCharset设置为false 并使用我们想要的字符集构建httpheader

RestTemplate restTemplate = new RestTemplate();
   List<HttpMessageConverter<?>> c = restTemplate.getMessageConverters();
        for(HttpMessageConverter<?> mc :c){
            if (mc instanceof StringHttpMessageConverter) {
                StringHttpMessageConverter mcc = (StringHttpMessageConverter) mc;
                mcc.setWriteAcceptCharset(false);
            }
   }

  HttpHeaders headers = new HttpHeaders();
  headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
  headers.setAcceptCharset(Arrays.asList(Charset.forName("UTF-8")));
  HttpEntity<String> entity = new HttpEntity<String>(jsonPayload, headers);

  restTemplate.postForEntity(postResourceUrl, entity, String.class);
RestTemplate RestTemplate=new RestTemplate();

列出@mushfek0001的答案产生两个
StringHttpMessageConverter
,它将发送两个
text/plain
*/*
,例如调试图片

甚至客户端的
Accept
标题也将是:

text/plain, text/plain, */*, */*
因此,更好的方法是删除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;
    }
}
RestTemplate RestTemplate=new RestTemplate();
StringHttpMessageConverter StringHttpMessageConverter=新的StringHttpMessageConverter(StandardCharsets.UTF_8);
stringHttpMessageConverter.setWriteAcceptCharset(true);
对于(int i=0;i
(由mushfek0001和zhouji添加到解决方案中)

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

UTF-8和ISO-8859之间的差异:

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

溶液1(从mushfek001复制): 解决方案2: 虽然上述解决方案可行,但正如周济所指出的,它将添加两个字符串转换器,并可能导致一些回归问题

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

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);


最好在添加新文件之前先删除StringHttpMessageConverter。这样,您将在MessageConverters列表中有一个StringHttpMessageConverter实例

RestTemplate restTemplate = new RestTemplate();
        final Iterator<HttpMessageConverter<?>> iterator = restTemplate.getMessageConverters().iterator();
        while (iterator.hasNext()) {
            final HttpMessageConverter<?> converter = iterator.next();
            if (converter instanceof StringHttpMessageConverter) {
                iterator.remove();
            }
        }


        restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
RestTemplate RestTemplate=new RestTemplate();
final Iterator converter=Iterator.next();
if(StringHttpMessageConverter的转换器实例){
iterator.remove();
}
}
restemplate.getMessageConverters().add(0,新的StringHttpMessageConverter(Charset.forName(“UTF-8”));

删除现有的转换器,但使用Java 8(为什么人们仍然编写Java 7代码?)

List试试这个

restTemplate.getMessageConverters().set(1,new StringHttpMessageConverter(Charsets.UTF_8));

你能为你的答案提供一些背景吗?这样,未来的读者就可以学习如何将它应用到他们的问题上,而不仅仅是在这种情况下。工作很有魅力。我有一个特殊的字符,看起来像'(单引号)的问题。在解析它时做了一个噩梦。价值1000英镑的简单调整votes@mushfek0001它没有帮助我改变如下所述。我能够更改字符集如何在字符集8和16之间切换为什么
.add(0,
而不仅仅是
.add(新字符串http…
?@mushfek0001更新字符集.forName(“UTF-8”)添加新的StringHttpMessageConverter对StandardCharsets.UTF_8很有帮助。解决方案2不是非标准内容类型的选项,如ElasticSearch REST API(应用程序/x-ndjson)中用于批量操作的内容类型。解决方案1可行,但解决方案2
headers.setContentType(MediaType.application_JSON_UTF8);
不起作用,sprint启动版本2.1.2,jdk 1.8解决方案2只使用headers.setContentType(MediaType.APPLICATION\u JSON\u UTF8);这是一个简单而优雅的解决方案。解释也很好。MediaType.APPLICATION_JSON_UTF8_值现在不推荐使用@Autowired RestTemplate吗?我没有注意到这样的问题。在我的例子中,Accept头的值
APPLICATION/JSON,APPLICATION/*+JSON
,这是可以的。我们可以对@Autowired RestTemplate也这样做吗?
// HttpUriRequest request
request.addHeader("Content-Type", MediaType.APPLICATION_JSON_UTF8_VALUE);
RestTemplate restTemplate = new RestTemplate();
        final Iterator<HttpMessageConverter<?>> iterator = restTemplate.getMessageConverters().iterator();
        while (iterator.hasNext()) {
            final HttpMessageConverter<?> converter = iterator.next();
            if (converter instanceof StringHttpMessageConverter) {
                iterator.remove();
            }
        }


        restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters();
converters.removeIf(httpMessageConverter -> httpMessageConverter instanceof StringHttpMessageConverter);
converters.add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));
restTemplate.getMessageConverters().set(1,new StringHttpMessageConverter(Charsets.UTF_8));