问题:我通过动态代理在过滤器中对get请求进行了乱码处理,而经过了转发后,正确的编码又变为乱码
解决前:
1、servlet中代码
<span style="white-space:pre"> </span>String uname = request.getParameter("uname");
System.out.println("get-2"+uname);
request.getRequestDispatcher("/d3").forward(request, response);
2、过滤器
// 强转
final HttpServletRequest hsr = (HttpServletRequest) request;
// post方式
hsr.setCharacterEncoding("utf-8");
// get方式
// 1.创建代理的对象
HttpServletRequest proxyHsr = (HttpServletRequest) Proxy.newProxyInstance(hsr.getClass().getClassLoader(),
hsr.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 是否是get请求
if ("get".equalsIgnoreCase(hsr.getMethod())) {
// 只增强getParameter方法
if ("getParameter".equals(method.getName())) {
// 获取乱码
String temp = (String) method.invoke(hsr, args);
String result = null;
try {
result = new String(temp.getBytes("iso8859-1"), "utf-8");
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
return method.invoke(hsr, args);
}
});
chain.doFilter(proxyHsr, response);
原因:在转发时 forward方法在转发之前对 getParameter进行了重写
1、 ApplicationHttpRequest类中进行的重写
@Override
public String getParameter(String name) {
parseParameters();
Object value = parameters.get(name);
if (value == null)
return (null);
else if (value instanceof String[])
return (((String[]) value)[0]);
else if (value instanceof String)
return ((String) value);
else
return (value.toString());
}
2、在上一个方法中调用了本类的一个方法parseParameters,代码如下:
if (parsedParams) {
return;
}
parameters = new HashMap<String, String[]>();
parameters = copyMap(getRequest().getParameterMap());
mergeParameters();
parsedParams = true;
其中 parsedParams是个布尔类型,默认为 false, parameters 是一个map集合,调用了原来的 getParameterMap方法,将返回的map集合copy到新的map中,所以解决方法:就是再将 getParameterMap也增强了,也就是对getParameterMap也进行get乱码解决
1、在过滤器中,在增强getParameter方法后面跟上增强getParameterMap方法
else if ("getParameterMap".equals(method.getName())) {
// 旧的
Map<String, String[]> map = (Map<String, String[]>) method.invoke(hsr, args);
Set<Entry<String, String[]>> entrySet = map.entrySet();
// 新的
Map<String, String[]> nmap = new HashMap<String, String[]>();
for (Entry<String, String[]> entry : entrySet) {
String[] value = entry.getValue();
String[] nval = new String[value.length];
for (int i = 0; i < value.length; i++) {
nval[i] = new String(value[i].getBytes("iso8859-1"), "utf-8");
}
nmap.put(entry.getKey(), nval);
}
return nmap;
}