乱码问题一直是 Java Web 开发的头疼事情,到底出现在数据库还是 Tomcat 或是 Servlet 或是前端?
笔者把自己项目中解决乱码的方案做些记录,注意实践中应根据情况快速定位问题的位置,而不是胡乱修改一些配置(虽然修改配置有时候也能成功)。
Tomcat 乱码
修改配置文件,server.xml,找到8080端口地方,加上URIEncoding="UTF-8"
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1"
redirectPort="8443" URIEncoding="UTF-8" />
Servelt Response 乱码
可以通过 System.out.println();
或者断点调试的方法确定乱码的来源。
笔者开始用 Java Application 写了一些方法,提示输出字符没有乱码。
但是用 Servlet 调用原先的方法输出到网页上就出现了乱码,可以猜测乱码出现在Servlet部分,可以尝试加上下面的代码。
resp.setContentType("text/html;charset=UTF-8");
// 目的是为了控制浏览器的行为,即控制浏览器用UTF-8进行解码;
resp.setCharacterEncoding("UTF-8");
Jsoup 解析 HTML 乱码
本来笔者是用 Get 请求某个 Url 获取Html,然后 Jsoup 对Html 请求解析成 Dom。但是总是会出现一小部分字符乱码问题,
最终还是改成了 Jsoup 自带的Jsoup.connect(url).get()解析页面。
// 利用get请求获取字符串再解析会有小部分乱码
// String htmlStr = HttpTool.doGet(urlStr);
// Document doc = Jsoup.parse(htmlStr);
//改用 Jsoup 自带的 connect
Document doc = Jsoup.connect(urlStr).timeout(10000).get();
public class HttpTool {
/**
* @param urlStr
* 网页链接
* @return 网页的 html 源码
*/
public static String doGet(String urlStr) throws CommonException {
URL url;
String html = "";
try {
url = new URL(urlStr);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setDoInput(true);
connection.setDoOutput(true);
if (connection.getResponseCode() == 200) {
InputStream in = connection.getInputStream();
html = StreamTool.inToStringByByte(in);
in.close();
} else {
throw new CommonException("新闻服务器返回值不为200");
}
} catch (Exception e) {
e.printStackTrace();
throw new CommonException("get请求失败");
}
return html;
}
}
public class StreamTool {
/**
* 利用ByteArrayOutputStream将流转化为字符串
*
* @param in
* 需要读取的InputStream
* @return 读取的字符串
* @throws Exception
*/
public static String inToStringByByte(InputStream in) throws Exception {
ByteArrayOutputStream outStr = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
// 这部分会不会有问题?,一个中文3个byte,如何确定1024最末尾的正好是一个中文,但打印出来乱码部分并不是1024结尾部分。
int len = 0;
StringBuilder content = new StringBuilder();
while ((len = in.read(buffer)) != -1) {
content.append(new String(buffer, 0, len, "UTF-8"));
}
outStr.close();
return content.toString();
}
}