Android中OkHttp的UTF-8编码问题:无法正确传输瑞典字符
你遇到的核心问题主要是自定义Content-Type请求头被OkHttp覆盖,以及请求体格式与Content-Type不匹配,最终导致瑞典字符编码异常。我来帮你一步步理清并解决:
为什么你的Content-Type头没生效?
你手动添加了application/json; charset=utf-8的请求头,但服务器日志显示实际生效的是application/x-www-form-urlencoded——这是因为你使用的FormBody是OkHttp专门用于表单提交的请求体,它会自动为自己设置对应的Content-Type头,并且直接覆盖你手动添加的同名字段。
另外,你这里混淆了两种请求格式:FormBody对应表单提交(application/x-www-form-urlencoded),而application/json是JSON格式请求体的标识,这两种格式不能混用,这也是字符编码异常的关键原因之一。
正确的配置方式
场景1:发送表单请求(匹配你的代码场景)
如果你的接口确实是接收表单参数,完全不需要手动设置Content-Type。当你用FormBody.Builder传入UTF-8字符集后,OkHttp会自动生成包含charset=utf-8的正确Content-Type头。修正后的代码如下:
public static String testPost() throws IOException{ OkHttpClient okHttpClient = new OkHttpClient(); HttpUrl httpUrl = new HttpUrl.Builder() .scheme("https") .host("dev.ourdomainname.com") .addPathSegment("characterencoding") .build(); // 直接传入UTF-8字符集构建表单请求体 RequestBody requestBody = new FormBody.Builder(StandardCharsets.UTF_8) .add("text", "xxåäöÅÄÖxx") .build(); Request request = new Request.Builder() .url(httpUrl) // 移除手动添加的Content-Type,让FormBody自动生成正确的请求头 .post(requestBody) .build(); try (Response response = okHttpClient.newCall(request).execute()) { return "test completed"; } }
此时OkHttp会自动发送Content-Type: application/x-www-form-urlencoded; charset=utf-8的请求头,服务器就能正确解析瑞典字符了。
场景2:发送JSON请求(如果接口预期接收JSON)
如果你的接口是接收JSON格式参数,那么应该使用JSON格式的请求体,而非FormBody。代码示例如下:
public static String testPostJson() throws IOException{ OkHttpClient okHttpClient = new OkHttpClient(); HttpUrl httpUrl = new HttpUrl.Builder() .scheme("https") .host("dev.ourdomainname.com") .addPathSegment("characterencoding") .build(); // 构造包含瑞典字符的JSON字符串 String jsonBody = "{\"text\": \"xxåäöÅÄÖxx\"}"; // 指定JSON类型的Content-Type并明确UTF-8编码 RequestBody requestBody = RequestBody.create( MediaType.parse("application/json; charset=utf-8"), jsonBody ); Request request = new Request.Builder() .url(httpUrl) .post(requestBody) .build(); try (Response response = okHttpClient.newCall(request).execute()) { return "test completed"; } }
额外的服务器端确认
既然你提到HTML表单能正常传输字符,说明服务器端的UTF-8配置基本没问题,但可以再快速检查两个点:
- Tomcat的
server.xml中,Connector节点是否添加了URIEncoding="UTF-8",确保GET请求参数编码正确; - 应用的
web.xml是否配置了UTF-8编码过滤器,处理POST请求的参数编码。
内容的提问来源于stack exchange,提问作者Mats Andersson

