web-dev-qa-db-fra.com

Comment puis-je dire à RestTemplate de POST avec l'encodage UTF-8?

Je ne parviens pas à publier JSON avec le codage UTF-8 à l'aide de RestTemplate. Le codage par défaut pour JSON étant UTF-8, le type de support ne doit même pas contenir le jeu de caractères. J'ai essayé de mettre charset dans le MediaType mais cela ne semble pas fonctionner de toute façon.

Mon code:

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);
27
anssias

Vous devez ajouter StringHttpMessageConverter pour que le convertisseur de messages du modèle repose sur charset UTF-8. Comme ça 

RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters()
        .add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
75
mushfek0001

(Ajout aux solutions de mushfek0001 et zhouji)

Par défaut, RestTemplate a ISO-8859-1 StringHttpMessageConverter qui est utilisé pour convertir un objet Java en requête de charge utile. 

Différence entre UTF-8 et ISO-8859: 

UTF-8 est un encodage multi-octets pouvant représenter n’importe quel Unicode personnage. ISO 8859-1 est un codage sur un octet pouvant représenter le 256 premiers caractères Unicode. Les deux encodent ASCII exactement de la même manière.

Solution 1 (copiée de mushfek001):

RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters()
        .add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));

Solution 2:

Bien que la solution ci-dessus fonctionne, mais comme l'a souligné zhouji, elle ajoute deux convertisseurs de chaîne et peut entraîner des problèmes de régression. 

Si vous définissez le bon type de contenu dans l'en-tête http, ISO 8859 se chargera de modifier les caractères UTF.

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

ou 

// HttpUriRequest request
request.addHeader("Content-Type", MediaType.APPLICATION_JSON_UTF8_VALUE);
8
Rohit

La réponse de @ mushfek0001 produit deux StringHttpMessageConverter qui enverront deux text/plain et */*, tels que l'image de débogage.

 enter image description here

Même l'en-tête Accept du client sera:

text/plain, text/plain, */*, */*

Donc, mieux vaut supprimer ISO-8859-1 StringHttpMessageConverter et utiliser un seul UTF-8 StringHttpMessageConverter.

Utilisez ceci:

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;
    }
}
6
zhouji

Mieux vaut supprimer d’abord le StringHttpMessageConverter avant d’en ajouter un nouveau. Ainsi, vous aurez ainsi une instance de StringHttpMessageConverter dans notre liste MessageConverters.

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")));
0
pankaj desai

Ajouter un nouveau StringHttpMessageConverter ne vous aidera pas. Dans StringHttpMessageConverter existant, nous devons définir writeAcceptCharset sur false .__ et construire httpheader avec le jeu de caractères souhaité.

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);
0
Sandesh
restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(StandardCharsets.UTF_16LE));

String response = restTemplate.getForObject(url, String.class);
0
Ran Adler