乱码出现的原因
在我们向服务端到客户端,或者相反,传送或者接收数据时候,如果编码解码不一致,就会出现乱码现象;
常见的几种中文编码格式: GB2312,iso-8859-1,UTF-8,GBK
Tomcat 默认的编码格式为:iso-8859-1
解决思路
解决乱码有很多办法,比如修改tomcat中config下面的web.xml文件,或者直接在接收发送的servlet中指定编码(麻烦,不推荐,每个servlet都要写重复的代码).
我今天向大家介绍动态代理解决全局乱码:
思路:
1.实现与HttpServletRequest相同接口的代理对象
2.在程序运行过程中对getParameter(String name)方法进行修改前逻辑的增强.
3.返回一个增强的HttpServletRequest对象
代码实现
总体视图
package com.tangbaobao.code;
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.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*@author 唐学俊
*@Version 2017年11月18日上午8:58:10
*使用动态代理来解决全局乱码问题
*/
public class CodeFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//增强request,response
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
req = EnhanceRequest(req);
//放行
chain.doFilter(req, response);
}
private HttpServletRequest EnhanceRequest(HttpServletRequest req) {
//获取Proxy代理对象
HttpServletRequest EnhanceReq = (HttpServletRequest) Proxy.newProxyInstance(
req.getClass().getClassLoader(),
req.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//获取对象方法
String name = method.getName();
if(name.equals("getParameter")) {
//获取乱码的字符串
String invoke = (String) method.invoke(req, args);
invoke = new String(invoke.getBytes("iso-8859-1"),"UTF-8");
return invoke;
}
return method.invoke(req, args);
}
}
);
return EnhanceReq;
}
}
package com.tangbaobao.code;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*@author 唐学俊
*@version 2017年11月18日上午9:44:14
*接收客户端传递过来的表单
*/
public class IndexServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
System.out.println(username);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
<%--客户端提交表单数据 --%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/index" method = "post">
<input type ="text" name ="username">
<input type = "submit" value = "提交">
</form>
</body>
</html>
总结
相对传统的增强方法,使用动态代理解决全局乱码很方便;在使用以上方法解决全局乱码,记得把Filter作用域配置 /*,并且jsp页面的编码格式和workspace的编码格式都修改与你的理想编码格式一致;
<filter-mapping>
<filter-name>CodeFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>