복붙노트

[SPRING] UTF-8 인코딩으로 RestTemplate에 POST 할 수있는 방법은 무엇입니까?

SPRING

UTF-8 인코딩으로 RestTemplate에 POST 할 수있는 방법은 무엇입니까?

RestTemplate을 사용하여 JSON을 UTF-8 인코딩으로 게시하는 데 문제가 있습니다. JSON의 기본 인코딩은 UTF-8이므로 미디어 유형에 charset이 포함되지 않아야합니다. MediaType에 charset을 넣으려고했지만 어쨌든 작동하지 않습니다.

내 코드 :

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

해결법

  1. ==============================

    1.charset UTF-8을 사용하여 템플릿의 메시지 변환기를 다시 사용하려면 StringHttpMessageConverter를 추가해야합니다. 이처럼

    charset UTF-8을 사용하여 템플릿의 메시지 변환기를 다시 사용하려면 StringHttpMessageConverter를 추가해야합니다. 이처럼

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

    2.(mushfek0001과 zhouji의 솔루션에 추가)

    (mushfek0001과 zhouji의 솔루션에 추가)

    기본적으로 RestTemplate에는 JAVA 객체를 페이로드 요청으로 변환하는 데 사용되는 ISO-8859-1 StringHttpMessageConverter가 있습니다.

    UTF-8과 ISO-8859의 차이점 :

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

    위의 솔루션이 작동하지만 zhouji가 지적했듯이 두 개의 문자열 변환기가 추가되어 회귀 문제가 발생할 수 있습니다.

    http 헤더에 올바른 내용 유형을 설정하면 ISO 8859가 UTF 문자를 변경합니다.

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

    또는

    // HttpUriRequest request
    request.addHeader("Content-Type", MediaType.APPLICATION_JSON_UTF8_VALUE);
    
  3. ==============================

    3.@ mushfek0001의 대답은 두 개의 StringHttpMessageConverter를 생성합니다.이 두 StringHttpMessageConverter는 디버그 그림과 같이 두 개의 text / plain과 * / *를 보낼 것입니다.

    @ mushfek0001의 대답은 두 개의 StringHttpMessageConverter를 생성합니다.이 두 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;
        }
    }
    
  4. ==============================

    4.

    restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(StandardCharsets.UTF_16LE));
    
    String response = restTemplate.getForObject(url, String.class);
    
  5. ==============================

    5.새로운 StringHttpMessageConverter를 추가해도 도움이되지 않습니다. 기존 StringHttpMessageConverter에서 writeAcceptCharset을 false로 설정해야합니다. 우리가 원하는 charset으로 httpheader를 빌드하십시오.

    새로운 StringHttpMessageConverter를 추가해도 도움이되지 않습니다. 기존 StringHttpMessageConverter에서 writeAcceptCharset을 false로 설정해야합니다. 우리가 원하는 charset으로 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);
    
  6. ==============================

    6.새로 추가하기 전에 StringHttpMessageConverter를 먼저 제거해야합니다. 이렇게하면 MessageConverters 목록에 StringHttpMessageConverter 인스턴스가 하나씩 생깁니다.

    새로 추가하기 전에 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")));
    
  7. ==============================

    7.기존 변환기를 제거하지만 Java 8을 사용합니다 (왜 사람들은 여전히 ​​Java 7 코드를 작성합니까?)

    기존 변환기를 제거하지만 Java 8을 사용합니다 (왜 사람들은 여전히 ​​Java 7 코드를 작성합니까?)

    List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters();
    converters .removeIf(httpMessageConverter -> httpMessageConverter instanceof StringHttpMessageConverter);
    messageConverters
      .add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));
    
  8. from https://stackoverflow.com/questions/29392422/how-can-i-tell-resttemplate-to-post-with-utf-8-encoding by cc-by-sa and MIT license