一、原因分析
解码的字符集和编码字符集的不一致
数据来源 | 默认编码格式 |
---|---|
浏览器页面 | GBK |
request(get) | ISO-8859-1 |
request(post) | GBK(同浏览器),但是如果是服务器来的页面一般已经设置了UTF-8(例如JSP提交的页面) |
Servlet(response) | ISO-8859-1 |
二、乱码处理方式
1.服务器端接收中文乱码
解决post提交方式的乱码
request.setCharacterEncoding("UTF-8");
解决get提交方式的乱码
//先以默认方式解码,再以uft-8编码
String str = newString(str.getbytes("iso8859-1"),"utf-8");
采用过滤器Filter和Proxy动态代理解决Get/Post方法乱码问题(对request方法进行增强)
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.mark.demo.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
//为解决全站乱码
public class CharacterEncodingFilter implements Filter {
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//对get提交的数据还是没有办法对其改变编码,所以要对request的getParameter方法缺少功能了
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//放行的是自己的包装类
MyCharacterEncodingRequest requestWrapper = new MyCharacterEncodingRequest(
request);
chain.doFilter(requestWrapper, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
/*
* 1.实现与被增强对象相同的接口2.定义一个变量记住被增强对象3.定义一个构造器,接收被增强对象
* 4.覆盖需要增强的方法 5.对于不想增强的方法,直接调用被增强对象(目标对象)的方法
*/
// 包装类
class MyCharacterEncodingRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;
// 接受被增强对象
public MyCharacterEncodingRequest(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) {
try {
// 客户机提交的值
String value = this.request.getParameter(name);
if (value == null) {
return null;
}
// 判断客户机的提交方式是不是get。这里忽略了get和GET方式
if (!this.request.getMethod().equalsIgnoreCase("get")) {
return value;
}
//客户机的原始码表
value = new String(value.getBytes("ISO8859-1"),
this.request.getCharacterEncoding()); //获取上面的request设定的编码
return value;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
2.前端页面接收中文乱码
response.setContentType("text/html;charset=UTF-8");