Mat*_*son 5 java android utf-8 character-encoding okhttp
我有一个关于 Android 中的 OkHttp 及其对字符编码的支持的问题,特别是使用 UTF-8 来支持瑞典字符 å、ä 和 ö(以及大写字母 ÅÄÖ)。
我们正在构建的应用程序使用 OkHttp 对我们的服务器系统进行 GET 和 POST 调用。服务器在 Apache 后面的 Tomcat 上运行。默认情况下,Apache 和 Tomcat 都配置为使用 UTF-8 字符编码。我假设需要的是从 Android 应用程序发送到服务器的 http 请求都配备了一个包含“application/text; charset=utf-8”之类的标头。
我构建了这个精简的代码示例来说明这个问题。如您所见,我在设置标头的请求中包含了 addHeader()。我还在 RequestBody 上主动设置了一个字符集。
public static String testPost() throws IOException{
OkHttpClient okHttpClient = new OkHttpClient();
HttpUrl.Builder builder = new HttpUrl.Builder();
HttpUrl httpUrl = builder.scheme("https")
.host("dev.ourdomainname.com")
.addPathSegment("characterencoding")
.build();
Charset charset = Charset.forName(StandardCharsets.UTF_8.name());
RequestBody requestBody = new FormBody.Builder(charset)
.add("text", "xxåäöÅÄÖxx")
.build();
Request request = new Request.Builder()
.url(httpUrl)
.addHeader("Content-Type", "application/json; charset=utf-8")
.post(requestBody)
.build();
Response response = okHttpClient.newCall(request).execute();
return "test completed";
}
Run Code Online (Sandbox Code Playgroud)
在服务器端,我记录了名为 text 的参数的值,它以“xxåäöÃ?Ã?Ã?xx”的形式出现,这当然不够好。我还有代码循环请求中的所有标头并记录它们。输出如下所示。注意没有“application/text; charset=utf-8”标题。
DEBUG 23 Jan 14:52:37.128 - testCharacterEncoding. text: xxåäö���xx
DEBUG 23 Jan 14:52:37.129 - Header: content-type with value: application/x-www-form-urlencoded
DEBUG 23 Jan 14:52:37.129 - Header: content-length with value: 45
DEBUG 23 Jan 14:52:37.129 - Header: host with value: dev.cqrify.com
DEBUG 23 Jan 14:52:37.129 - Header: connection with value: Keep-Alive
DEBUG 23 Jan 14:52:37.129 - Header: accept-encoding with value: gzip
DEBUG 23 Jan 14:52:37.129 - Header: user-agent with value: okhttp/3.9.1
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:我们这样做是否错误?如果是,那么正确的方法是什么?最坏的情况,这可能是 OkHttp 中的一个错误,但我对此表示怀疑。
为了比较,我构建了一个简单的 html 表单来制作完全相同的帖子,并且以这种方式发送的相同字符串作为“xxåäöÅÄÖxx”出现,这是正确的。
这里至少存在两个不同的问题。
\n\n1.您的 Content-type 标头被(正确地)忽略
\n\n当您稍后调用对象时,您设置的 Content-type 标头将被.post(requestBody)覆盖request。这是因为您正在使用一个FormBuilder对象来构建 POST 正文,并且该对象专门用于表单application/x-www-form-urlencoded。如果你想发布 JSON 数据,你不应该使用它。相反,试试这个:
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");\nOkHttpClient client = new OkHttpClient();\n\nString post(String url, String json) throws IOException {\n RequestBody body = RequestBody.create(JSON, json);\n Request request = new Request.Builder()\n .url(url)\n .post(body)\n .build();\n[...]\nRun Code Online (Sandbox Code Playgroud)\n\n这是官方 OkHttp 示例的完整源代码。
\n\n2.非ASCII字符乱码
\n\n即使您坚持使用application/x-www-form-urlencoded内容类型,非 ASCII 文本也应该可以正常工作。那么你的情况是怎么回事?
我怀疑你编译源代码时存在编码问题;即 javac 使用的字符集与 Java 源文件的字符集不匹配。您可能希望显式地将-encoding utf8(或您在源文件中使用的任何编码)传递给 javac,或者更好的是,避免源代码中出现任何非 ASCII 字符并使用 Unicode 转义符。在这种情况下,xx\xc3\xa5\xc3\xa4\xc3\xb6\xc3\x85\xc3\x84\xc3\x96xx您可能想要使用而不是xx\\u00E5\\u00E4\\u00F6\\u00C5\\u00C4\\u00D6xx
| 归档时间: |
|
| 查看次数: |
12038 次 |
| 最近记录: |