REST查询中的UTF-8编码字符未正确呈现

时间:2015-02-12 15:16:39

标签: rest grails character-encoding

我正在使用外部REST服务,该服务提供UTF-8编码的所有内容。

由于某些原因,我的应用程序无法正确处理响应。如果我拒绝回复,我会选择LuleÃ¥(应该是Luleå)。

编辑: 如果我将字符串转发(不改变)到UI,则会发生相同的行为,例如:

flash.message = "Test" + integrationService.testEncoding()

我所做的是在/ script文件夹中创建_Events.groovy文件并在那里指定

eventConfigureTomcat = { tomcat ->
    tomcat.connector.URIEncoding = "UTF-8"
    tomcat.connector.useBodyEncodingForURI = true
}

我的Config.groovy

中也有以下内容:
grails.views.gsp.encoding = "UTF-8"
grails.converters.encoding = "UTF-8"

但这没有改变。答案仍然错误地显示出来。我不确定这是Grails的配置问题,嵌入式tomcat还是其他东西。我目前正在Windows 7上运行我的测试设置,但同样的问题发生在我在Centos上运行的服务器上。请指教。

EDIT2: 如果我使用curl使用REST服务,则所有内容都在输出中正确呈现。

EDIT3: 我正在使用org.springframework.web.client.RestTemplateHttpComponents来使用该服务:

private static final HttpHeaders requestHeaders
static{
    requestHeaders = new HttpHeaders()
    requestHeaders.set(HttpHeaders.CONTENT_TYPE, "application/json")
    requestHeaders.set(HttpHeaders.ACCEPT, "application/json")
    requestHeaders.set("Accept-Encoding", "gzip")
}

private final static RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory(
    HttpClientBuilder.create().build()))
...
...
public def testEncoding(){
    ResponseEntity<String> response = restTemplate.exchange(
            "https://www.url.com", HttpMethod.GET, new HttpEntity<Object>(requestHeaders),
            String.class)
    def gamesJson = JSON.parse(response.getBody())
    //...
    //parse value from gamesJson
    //...
    return testValue
}

5 个答案:

答案 0 :(得分:7)

my previous answer

您只需将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);

答案 1 :(得分:2)

编码类型可以在环境中强制执行。

JAVA_TOOL_OPTIONS -Dfile.encoding = UTF8 -Dclient.encoding.override = UTF-8

尝试在windows / linux中设置上述编码设置。我希望这可以解决这个问题。

在这种情况下,JVM将从环境变量中拾取默认编码类型。

答案 2 :(得分:1)

我们的团队之前遇到过类似的问题,我们有第三方服务,他们说他们的输出是用UTF-8编码的。但返回的字符串仍然是乱码。经过一些测试,结果发现他们正在返回 ISO-8859-1 编码的字符串。我们所做的是将输入解码/编码为UTF-8编码字符,以便我们正确使用它们。

对于您的情况,我认为这是一个类似的问题:

  

UTF-8:Luleå

     

ISO-8859-1:Luleå

在Java中,我们做了类似的事情:

Charset initialEncoding = Charsets.ISO_8859_1;
Charset outputEncoding = Charsets.UTF_8; 
byte[] byteArray = input.getBytes(initialEncoding);
String output = new String(new String(byteArray, outputEncoding));

在Groovy中,我认为你可以做类似

的事情
import groovy.json.JsonSlurper;

def main = {
    def response = '{"name":"Luleå"}' 

    def slurper = new JsonSlurper()
    def result = slurper.parse(response.getBytes(), 'UTF-8')

    println result.name // prints Luleå
}

答案 3 :(得分:1)

我的问题的答案已经是found on Stack Exchange

  

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

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

答案 4 :(得分:0)

在我的情况下,我对从服务器而不是本地环境从REST Web服务接收的内容有相同的问题。 我进行了很多搜索,终于找到了解决问题的解决方案。 在Windows中,我添加了一个键为JAVA_TOOL_OPTIONS的新环境变量,并将其值设置为:-Dfile.encoding=UTF8。 每次启动JVM时,都会自动设置(Java)系统属性。您将知道该参数已被拾取,因为以下消息将发布到System.err:

Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8