Java Web中出现乱码的现象:
第一类:前台参数传输至服务端后乱码
1. get请求参数中文发送到服务器端乱码
2. post请求参数中文发送到服务器乱码
第二类:服务端响应到达浏览器后乱码
3. 在 jsp 页面中,中文显示乱码
Java Web中出现的各种 编码 :
1. JSP文件自身的编码
Jsp文件中会出现下面所示的编码指定方式:
<%@ page language=“java” contentType=“text/html; charset= utf-8 ″ pageEncoding=“UTF-8″%>
< Meta http-equiv=“Content-Type” content=“text/html; charset=UTF-8″>
1)pageEncoding=”utf-8″ –该jsp文件自身采用的编码格式,也就是告诉服务器使用什么编码翻译jsp文件成java文件
jsp中post表单的编码由pageEncoding和contentType参数决定,以pageEncoding为准,如果没有pageEncoding则以contentType为准,如果没有contentType以Meta标签中的charset为准,都没有则以ISO-8859-1编码
2)contentType=”text/html;charset=utf-8″服务器发送浏览器的数据类型和内容编码。其中charset=”utf-8″–用来指定 Tomcat 返回响应时采用的编码,也是post方式提交参数的编码方式。
3)Meta标签中的charset是在contentType未指定编码时采用的默认编码格式
2. Tomcat读取JSP文件时采用的编码
参考1)
3. Tomcat返回响应时采用的编码
参考2)
4. 浏览器显示HTML时采用的编码
浏览器的编码格式的设置
根据现象分析解决方案:
1. get请求参数乱码

2. post请求参数乱码
POST表单参数是通过http的body传递到服务器的。前面已经说过,表单项参数是采用contentType中的charset指定的编码格式进行编码的。服务器端也是用contentType中的charset指定的编码进行解码操作,所以一般不会出现乱码问题。

这个编码我们可以通过 request .setCharacterEncoding()来进行设置,该设置只对POST参数有效。注意,这个函数必须在第一次调用request.getParameter()之前使用。
3. 同时处理Get和Post两种提交方式的编码问题
GET和POST两种方式的不同表现使得处理起来比较麻烦。
根据1和2,使用组合方法可以确定多种解决策略。
解决方案1:分别处理get和post请求
处理get请求:在Tomcat的 server .xml下的connector属性中添加参数URIEncoding=’UTF-8’;
处理post请求:在 servlet 中设置request.setCharacterEncoding()
解决方案2:都使用手动重新解码
以上两种方式存在一个共同的问题,那就是只要请求中有中文,每一个servlet都要进行重复的处理。应该抽取出这个过程。
解决方案3:使用参数useBodyEncodingForURI=’true’
在Tomcat的server.xml下的connector属性中添加参数useBodyEncodingForURI=’true’(注意,并不是对整个URI都采用BodyEncoding,只是应用于Query String而已)。这样,Tomcat便会用request.setCharacterEncoding()指定的编码来解析GET参数了。
解决方案4:使用过滤器 Filter 并运用动态代理实现编码统一处理
package EncodingFilter;
import java.io.IOException;
import java. lang .reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class EncodingFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
// 如果希望匿名内部类使用一个在外部定义的对象,那么编译器会要求其参数引用是final的
final HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
request.setCharacterEncoding(“UTF-8”);// POST提交有效
response.setContentType(“text/html;charset=UTF-8”);
// 解决:对HttpServletRequest接口的getParameter方法进行功能扩展,识别GET请求,可以使用动态代理!
HttpServletRequest proxyRequest = (HttpServletRequest) Proxy.newProxyInstance(request.getClass().getClassLoader(),
new Class[] { HttpServletRequest.class },
new InvocationHandler() {
// args对象数组,代表被调用方法的参数
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
String methodName = method.getName();
if (“getParameter”.equals(methodName)) {
String value = request.getParameter(args[0]
.toString());
String requestMethodName = request.getMethod();
if (“GET”.equals(requestMethodName)) {
// 不为空 也不为 空字符串
if (value != null && !””.equals(value.trim())) {
value = new String(value
.getBytes(“iso-8859-1”), “utf-8”);
}
}
return value;
} else {
return method.invoke(request, args);
}
}
});
//放行 (执行下一个过滤器或者servlet)
chain.doFilter(proxyRequest, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
}
}
再在web.xml中配置filter和filter-mapping,搞定
4. 服务器发送给浏览器的乱码问题

5. 在jsp页面中,中文显示乱码

总结
开发时应注意工作区编码,前端编码,服务器编码,数据库编码一致。
造成乱码的原因就是因为使用了错误的字符编码去解码字节流,因此当我们在思考任何跟文本显示有关的问题时,请时刻保持清醒:当前使用的字符编码是什么。