【问题标题】:Java Spring resttemplate character encodingJava Spring resttemplate 字符编码
【发布时间】:2015-02-20 14:48:16
【问题描述】:

我正在使用 Java Spring Resttemplate 通过获取请求获取 json。我得到的 JSON 有一些奇怪的东西,而不是像 ü ö ä 或 ß 这样的特殊字符。所以我猜字符编码有问题。我在互联网上找不到任何帮助。我现在使用的代码是:

String json = restTemplate.getForObject(
    overPassStatementPostCode,
    String.class,
    params);

【问题讨论】:

  • 什么是overPassStatementPostCode?请发布更多代码,包括您对应的 POJO。
  • 您正在设置String.class,它将使用StringHttpMessageConverter。您可以尝试使用MappingJackson2HttpMessageConverter。例如。 ` ArrayList> messageConverters = new ArrayList>(); messageConverters.add(new MappingJackson2HttpMessageConverter()); restTemplate.setMessageConverters(messageConverters); `
  • 看源码,我们也可以把charset传给StringHttpMessageConverter(),可以传UTF-8charset,因为defaultCharSet是ISO-8859-1
  • 对不起,我不明白如何在代码中设置 charSet。 overPassStamementPostCode 只是一个带有占位符的字符串。它被 params Map 中的参数填充。
  • 我可以用这样的代码创建一个 StringMessageConverter: StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));但我只是找不到如何将他的转换器与我的 http get 请求一起使用的方法。感谢您的帮助。

标签: java json utf-8 character-encoding resttemplate


【解决方案1】:

您只需将StringHttpMessageConverter 添加到模板的消息转换器:

RestTemplate template = new RestTemplate();
template.getMessageConverters()
        .add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
ResponseEntity<Object> response = template.exchange(endpoint, method, entity, 
                                                    Object.class);

【讨论】:

  • 已解决my encoding 问题。如果您想要赏金,请在此处写下答案。否则我会在这里链接并写下自己的答案。
  • 你的帖子刚刚结束了 2 小时的拉扯我的头发,谢谢伙计
  • 2018 年的问候。只是过来告诉你,我爱你解决了我的问题!
  • 显然索引很重要。没有 0 对我来说它是行不通的。
  • @beerbajay:我在使用这种方法时遇到了一个问题。如果我们在春季对RestTemplate 使用DI(依赖注入)并使用这种方法对UTF-8 进行编码,那么我们将得到Encountered Exception during request : java.util.ConcurrentModificationException有没有更好的解决方案!
【解决方案2】:

我在这个案例上遇到了同样的问题,经过一次搜索,我得到了这个链接: https://gist.github.com/knight1128/66f3e4817ab35c7397fd

它的解决方法对我有用:

package com.google.locationlab;

import com.google.common.collect.Lists;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.springframework.http.*;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.nio.charset.Charset;
import java.util.List;

public class PortalRestTemplateIntegrationTest {
    private Log logger = LogFactory.getLog(PortalRestTemplateIntegrationTest.class);

    @Test
    public void test() throws Exception {
        RestTemplate restTemplate = new RestTemplate();

        HttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
        List<HttpMessageConverter<?>> httpMessageConverter = Lists.newArrayList();
        httpMessageConverter.add(stringHttpMessageConverter);
        restTemplate.setMessageConverters(httpMessageConverter);

        URI targetUrl= UriComponentsBuilder.fromUriString("http://portal.net")
                .path("search")
                .queryParam("q", "잠실역")
                .build()
                .toUri();

        HttpHeaders headers = new HttpHeaders();
        Charset utf8 = Charset.forName("UTF-8");
        MediaType mediaType = new MediaType("text", "html", utf8);
        headers.setContentType(mediaType);
        headers.set("User-Agent", "mozilla");
        headers.set("Accept-Language", "ko"); 
        // gzip 사용하면 byte[] 로 받아서, 압축을 풀고 decoding 해야 한다. 

        HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
        ResponseEntity<String> responseEntity = restTemplate.exchange(targetUrl.toURL().toString(), HttpMethod.GET, entity, String.class);
        String result = responseEntity.getBody();

        logger.info(result);

    }
}

【讨论】:

  • StandardCharsets.UTF_8 是否优于 Charset.forName("UTF-8")?
【解决方案3】:

首先我尝试了@beerbajay的方式,但没有帮助。最后我通过以下方式解决了它

        RestTemplate template = new RestTemplate();
//      template.getMessageConverters()
//              .add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(newArrayList(MediaType.APPLICATION_JSON));
        ResponseEntity<String> response = template.exchange(url, HttpMethod.GET, new HttpEntity<String>(headers), String.class);

【讨论】:

    【解决方案4】:

    我已经解决了这个问题。我需要使用 UTF-8 在请求正文中发布一个字符串对象。

    文本/纯文本

    httpHeaders.setContentType(new MediaType("text", "plain", StandardCharsets.UTF_8));

    应用程序/json

    httpHeaders.setContentType(new MediaType("application", "json", StandardCharsets.UTF_8));

    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<String> resposeEntity = null;
    
    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.setContentType(new MediaType("text", "plain", StandardCharsets.UTF_8));
    
    HttpEntity<String> httpEntity = new HttpEntity<String>(stringContent, httpHeaders);
    responseEntity = restTemplate.exchange(requestUrl, HttpMethod.POST, httpEntity, String.class);
    
    if (HttpStatus.OK.equals(responseEntity.getStatusCode())) {
        logger.debug("... success ... result: " + responseEntity.getBody());
    }
    

    【讨论】:

      【解决方案5】:

      如果您可以执行以下操作,您仍然可以使用 String.class 作为响应类型。

      升级到 spring-web 5.2 解决了这个问题。或将 writeAcceptCharset 属性设置为 false 属于 StringHttpMessageConverter 并在 RestTemplate 实例中进一步使用该转换器。

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

      【讨论】:

        猜你喜欢
        • 2015-03-02
        • 1970-01-01
        • 2014-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多