乱码的原因和处理
1.乱码原因:
造成乱码的原因主要是前端页面的编码格式和服务端编码格式的不同,这就造成了对中文处理时发生乱码。我们常用的编码字符集有一下几种:
1.ISO-8859-1:只取一个字节
2.GBK-GB2312:汉字占用2个字节
3.UTF-8:一个汉字占用3个字节
所以ISO编码是不能用来存储中文的。我们要使用GBK或UTF-8,这样中文编码过程为:
浏览器(输入):
我是乱码----通过GBK进行编码得到:aabbcc-----通过ISO进行编码得到:112233 这个过程是浏览器自动执行的
程序员最终获得的数据是112233,如果后台(代码里)使用的是utf-8,那么将112233通过utf-8解码是得不到正确的中文的。
2.解决办法:
1.对页面后台进行统一字符。例如在JSP中将pageEncoding设置为GBK,那么在Myeclipse中将项目的编码格式也指定为GBK。那么程序员就能得到aabbcc在使用GBK解码就能得到正确的中文。
缺点:只对Post提交方式有用。因为pageEncoding这个只对post起作用。get方法提交时,大家可以从地址栏里看到提交的参数,这是因为get方法传递是作为报文头提交的,而 pageEncoding对报文头是没有作用的,所以仍然按照 iso8859-1编码,才出现了刚才的乱码问题。而post提交的是form表单的内容,pageEncoding指定了它的编码,所以他会按照指定编 码传递。
2.从过程上进行解决:
程序员(获得):
得到112233---进行ISO解码得到:aabbcc------在通过GBKj解码得到:我是乱码
这样的话就不会造成乱码了。
若后台(代码)使用的是GBK,那么还原过程:
String msg = request.getParameter("msg");
byte[] newMsg = msg.getBytes("ISO-8859-1");//通过ISO-8859-1获得该字符串的字节数组
String res = new String(newMsg, "GBK");
这种办法对get和post都适用。
3.在后台(代码中)直接指定request和response的编码格式,使之和前端(JSP)里的编码格式一样
response.setContentType("text/html; charset=GB2312");
request.setCharacterEncoding("GBK");
缺点:和用pageEncoding一样只适用于post方式
5.使用过滤器(对取得的值直接进行编码转换,这种方法对get和post都适用)
具体操作:
1.在web.xml文件中 在servlet前添加过滤器filter:
<filter> <filter-name>EncodingFilter</filter-name> <filter-class>com.filter.EncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>2.定义自己的request和response
/*
* 该类用来定义自己的request,彻底解决request的乱码问题,同理可以完成response的乱码问题
*/
public class MyRequestWrapper extends HttpServletRequestWrapper{
private String charset;
public MyRequestWrapper(HttpServletRequest request) {
super(request);
}
public MyRequestWrapper(HttpServletRequest request, String charset) {
super(request);
this.charset = charset;
}
@Override
public String getParameter(String na) {
String value = null;
try {
if(super.getParameter(na)!=null){
value = new String(super.getParameter(na).getBytes("iso-8859-1"),charset);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return value;
}
}
3 .新建一个类 实现Filter接口, 将ServletRequest,ServletResponse转化成HttpServletRequest 和 HttpServletResponse
/*
* 该类用来进行编码转换
*/
public class AuthorityFilter implements Filter
{
private String charset;
public void destroy() {
}
//放行所有请求和响应
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;//强制转换httpservlet
HttpServletResponse resp = (HttpServletResponse) response;
//req.setCharacterEncoding("UTF-8");直接设置编码格式
req.setCharacterEncoding(charset);//通过xml配置编码格式
if(charset != null){
req = new MyRequestWrapper(req, charset);
}
chain.doFilter(req, resp);//放行所有请求和响应,必须使用转换后的req,resp,否则编码没有转换
}
//有条件的放行,对于登录页面不放行
public void doFilter2(ServletRequest req, ServletResponse resp,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
String path = request.getContextPath();
String uri = request.getRequestURI();
String str = uri.substring(path.length());
HttpSession session = request.getSession();
if(str.startsWith("/system") && !str.endsWith("login.jsp")){
if(session.getAttribute("user") == null){
response.sendRedirect("login.jsp");
}
}
//放行
filterChain.doFilter(request, response);
}
//设置转换编码格式
public void init(FilterConfig filterConfig) throws ServletException {
this.charset = filterConfig.getInitParameter("encoding");
}
}