在J2EE项目中,常见的乱码一般都是中文乱码。这里不讲平时你们遇到的那些乱码问题。
平时遇到的乱码,注意编码环境和解密环境统一编码就好。比如浏览器默认的是ISO-8859-1编码等。
这里讲一个我遇到的乱码例子,以及分析过程:
问题场景:
我这边是一个金融业务系统,对外提供API,对方作为业务的使用方,需要使用我的接口。通过http post的方式请求,我返回的响应报文格式为json。对方使用的http工具为apache的httpClien包。
1、我返回的json串格式,不管是中文还是英文,都是以UTF-8的形式返回。
2、对方服务器的编码环境也是UTF-8。
3、对方接收到的响应报文中,中文乱码。(问题)
分析过程:
1、起先,我先判断我返回报文的编码是不是UTF-8。服务器log日志中,中文正常显示。通过locale指令,查看到服务器编码是LANG=zh_CN.UTF-8。因此返回报文是UTF-8格式基本可以确定。
2、我用的是oracle数据库,查看到数据库中文的编码格式为GBK。开始怀疑是不是数据库中文编码和我程序中中文编码格式不一致。经过分析后,排除了这个想法。因为程序从数据库中查询出的中文,默认和程序的编码格式保持一致。
3、思考是否是http传输过程中,导致我utf-8格式返回的响应报文,编码变了。
因为我返回的报文格式是json格式,且使用的网络传输方式为http,于是,我注意到两个http请求头中的东西:Content-type和Accept。
Http报文头中,Content-type和Accept的区别:
1.Accept属于请求头, Content-Type属于实体头。
Http报头分为通用报头,请求报头,响应报头和实体报头。
请求方的http报头结构:通用报头|请求报头|实体报头
响应方的http报头结构:通用报头|响应报头|实体报头
2.Accept代表发送端(客户端)希望接受的数据类型。
比如:Accept:text/xml;
代表客户端希望接受的数据类型是xml类型
Content-Type代表发送端(客户端|服务器)发送的实体数据的数据类型。
比如:Content-Type:text/html;
代表发送端发送的数据格式是html。
Accept:text/xml;
Content-Type:text/html
即代表希望接受的数据类型是xml格式,本次请求发送的数据的数据格式是html。
于是我建议对方在http请求的时候,加入post.setHeader("Accept" ,"application/json");这一行代码,指定接收的报文的格式为json。成功解决了响应的json报文中乱码的问题。