最近在项目中碰到几次乱码问题,每次网上搜索下复制粘贴管用完事。现在有时间,捋一捋乱码的整体情况。
产生原因:发送方、接受方对数据的编解码不一致
乱码类型:请求参数乱码、返回结果乱码
解决思路:保持发送、请求编码解码一致
具体场景
客户端
Httpclient
请求参数编码设置:
- GET
URLEncoder.encode("杭州", "utf-8");
- POST
PostMethod method = new PostMethod();
method.addRequestHeader("Content-Type","text/html;charset=UTF-8");
- 返回编码设置
一般使用HttpMethodBase(GETMethod和PostMethod的父类)的getResponseBody系列方法获取响应数据,默认从服务器端给的response内中获取编码方式
response.setContentType("text/html;charset=UTF-8")
- 如果服务端无法修改,可以在读取流的时候指定编码方式
br = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), Charset.forName("UTF-8")));
HttpURLConnection(待续。。。)
服务端
SpringMVC
接收参数设置
- Get
#对参数重新编码
new String(bytes,”UTF-8”)
- Post
req.setCharacterEncoding("UTF-8");
- 通用解决办法,在web.xml设置过滤器
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param> <!--字符的编码格式 -->
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param> <!--强制使用Encoding设置的编码格式-->
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- 响应参数设置
在RequestMapping中增添produces参数设置
@RequestMapping(value ="/Demo",produces="application/json;charset=UTF-8")
乱码校验DEMO
通过尝试不同方式解码,可以用于检验在不同场景下发送方、接收方的编码方式。
备注:由于UTF-8特殊编码方式,有些字符是不可能出现在UTF-8编码中。经过UTF-8编码过的字符无法恢复。
**
* @ClassNameresolveErrorCode
* @Description
* @Author BigBear
* @Date2021/8/29 13:36
* @Version V1.0
**/
public class resolveErrorCode {
public static void recover(String str) throws Exception {
System.out.println("待解码内容:"+str);
String[] charsets = new String[]{"ASCII","ISO8859-1","GB2312","GBK","GB18030","BIG5","Unicode","UTF-8","UTF-16","UTF-32"};
for (int i=0; i<charsets.length; i++) {
for (int j=0; j<charsets.length; j++) {
if (i != j) {
String s = new String(str.getBytes(charsets[i]), charsets[j]);
System.out.println("先按照"+charsets[i]+"获取字符串的二进制:"+str.getBytes(charsets[i])+
",然后按"+charsets[j]+"编码解读这个二进制,得到一个新的字符串:"+s);
}
}
}
}
}
参考
https://blog.youkuaiyun.com/u010234516/article/details/52853214
https://blog.youkuaiyun.com/zhao1949/article/details/51543765