来自 REST 查询的 UTF-8 编码字符未正确呈现
UTF-8 encoded characters from REST-query not rendered properly
我正在使用一个外部 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 服务器 运行 上。请指教
编辑2:
如果我使用 curl 使用 REST 服务,输出中的所有内容都会正确呈现。
编辑3:
我正在使用 org.springframework.web.client.RestTemplate
和 HttpComponents
来使用服务:
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
}
可以在环境本身中强制执行编码类型。
JAVA_TOOL_OPTIONS -Dfile.encoding=UTF8 -Dclient.encoding.override=UTF-8
只需尝试在 windows/linux 中设置上述编码设置。我希望这可以解决问题。
在这种情况下,JVM 将从环境变量中获取默认编码类型。
我们的团队之前遇到过类似的问题,我们有一个第三方服务,他们说他们的输出是用 UTF-8 编码的。但是返回的字符串还是乱码。经过一些测试后,结果发现他们返回的是 ISO-8859-1 编码的字符串。我们所做的是 decode/encode 将他们的输入转换为 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å
}
我的问题的答案已经是 found on Stack Exchange。
You just need to add the StringHttpMessageConverter to the template's message converters:
restTemplate.getMessageConverters()
.add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
根据 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);
在我的例子中,我遇到了同样的问题,内容是从我的 REST Web 服务从服务器接收的,而不是我的本地环境。
我进行了很多搜索,最后找到了解决我问题的解决方案。
在 Windows 中,我添加了一个新的环境变量,键为:JAVA_TOOL_OPTIONS
并将其值设置为:-Dfile.encoding=UTF8
。
每次启动 JVM 时都会自动设置 (Java) 系统 属性。您将知道该参数已被拾取,因为以下消息将发布到 System.err:
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
我正在使用一个外部 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 服务器 运行 上。请指教
编辑2: 如果我使用 curl 使用 REST 服务,输出中的所有内容都会正确呈现。
编辑3:
我正在使用 org.springframework.web.client.RestTemplate
和 HttpComponents
来使用服务:
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
}
可以在环境本身中强制执行编码类型。
JAVA_TOOL_OPTIONS -Dfile.encoding=UTF8 -Dclient.encoding.override=UTF-8
只需尝试在 windows/linux 中设置上述编码设置。我希望这可以解决问题。
在这种情况下,JVM 将从环境变量中获取默认编码类型。
我们的团队之前遇到过类似的问题,我们有一个第三方服务,他们说他们的输出是用 UTF-8 编码的。但是返回的字符串还是乱码。经过一些测试后,结果发现他们返回的是 ISO-8859-1 编码的字符串。我们所做的是 decode/encode 将他们的输入转换为 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å
}
我的问题的答案已经是 found on Stack Exchange。
You just need to add the StringHttpMessageConverter to the template's message converters:
restTemplate.getMessageConverters()
.add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
根据 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);
在我的例子中,我遇到了同样的问题,内容是从我的 REST Web 服务从服务器接收的,而不是我的本地环境。
我进行了很多搜索,最后找到了解决我问题的解决方案。
在 Windows 中,我添加了一个新的环境变量,键为:JAVA_TOOL_OPTIONS
并将其值设置为:-Dfile.encoding=UTF8
。
每次启动 JVM 时都会自动设置 (Java) 系统 属性。您将知道该参数已被拾取,因为以下消息将发布到 System.err:
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8