1.动态代理实现
1>首先在web.xml中添加如下代码
<context-param>
<param-name>encode</param-name>
<param-value>utf-8</param-value>
</context-param>
<!-- filter配置 -->
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>cn.tedu.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2>在写一个类EncodingFilter继承Filter,代码如下
public class EncodingFilter{private String encode = null;
/**
* 初始化方法
*/
publicvoidinit(FilterConfig filterConfig) throws ServletException{
//获取ServletContext对象
ServletContext sc =filterConfig.getServletContext();
//读取初始化参数中的编码集配置
this.encode = sc.getInitParameter("encode");
}
/**
* 过滤方法
*/
publicvoid doFilter(final ServletRequest request, ServletResponse response,FilterChainchain) throws IOException,ServletException {
//解决乱码
//响应乱码
response.setContentType("text/html;charset="+encode);
//请求参数:创建动态代理
ServletRequest proxyRequest=
(ServletRequest) Proxy.newProxyInstance(request.getClass().getClassLoader(),request.getClass().getInterfaces(), newInvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//如果是调用getParameter方法
if("getParameter".equals(method.getName())){
//获取请求参数
String value =(String) method.invoke(request, args);
//重新编码并返回
return newString(value.getBytes("iso8859-1"),encode);
//如果是调用getParameterValues方法
}else if("getParameterValues".equals(method.getName())){
//获取请求参数组成的数组
String[] values= (String[]) method.invoke(request, args);
//遍历数组
for (int i = 0; i <values.length; i++) {
//对数组中每一个元素重新编码,并赋值给当前元素
values[i] = newString(values[i].getBytes("iso8859-1"),encode);
}
//返回编码后的数组
return values;
//如果是调用getParameterMap方法
}else if("getParameterMap".equals(method.getName())){
//获取请求参数组成的map
Map<String,String[]>map = (Map<String, String[]>) method.invoke(request, args);
//遍历map
for (Map.Entry<String, String[]>entry : map.entrySet()) {
String[]value = entry.getValue();
for (int i = 0; i <value.length; i++) {
value[i] = newString(value[i].getBytes("iso8859-1"),encode);
}
//将编码后的value赋值给map
map.put(entry.getKey(),value);
}
return map;
}else{
//如果是其他方法,直接执行目标方法并返回
return method.invoke(request, args);
}
}
});
//放行时,使用代理对象作为参数
chain.doFilter(proxyRequest,response);
}
/**
* 销毁方法
*/
publicvoid destroy() {
}
}2.装饰模式实现乱码问题
写一个类EncodingFilter继承Filter,代码如下
public class EncodingFilter{
private String encode = null;
/**
* 初始化方法
*/
publicvoidinit(FilterConfig filterConfig) throws ServletException{
//获取ServletContext对象
ServletContext sc =filterConfig.getServletContext();
//读取初始化参数中的编码集配置
this.encode = sc.getInitParameter("encode");
}
/**
* 内部类ServletRequest的装饰类 改造了获取请求参数相关的方法 增加了乱码解决的代码
*/
//继承了HttpServletRequestWrapper,这个父类本身就是 HttpServletRequest的装饰器 在其中提供方法的默认的实现 不想改造的方法不用管 想改造的方法 覆盖父类方法即可
class MyServletRequest extendsHttpServletRequestWrapper{
private ServletRequest request = null;
privatebooleanhasNotEncode = true;
//构造器 接受传入的request保存在类的内部
public MyServletRequest(HttpServletRequest request) {
super(request);
this.request = request;
}
//覆盖和获取请求参数相关的方法
@Override
public Map<String,String[]> getParameterMap() {
try {
//获取请求参数组成的map
Map<String,String[]>map = request.getParameterMap();
if(hasNotEncode){//由于request对此map会缓存所以解决乱码的操作 只需要做一次 此处通过hasNotEncode来控制
//遍历map
for (Map.Entry<String, String[]>entry : map.entrySet()) {
//获取当前遍历到的值的数组
String[]values = entry.getValue();
//遍历值的数组
for (int i = 0; i <values.length; i++) {
//解决乱码 存回数组
values[i]= newString(values[i].getBytes("iso8859-1"),encode);
}
}
hasNotEncode = false;
}
//返回解决完乱码的map
return map;
} catch (Exception e) {
e.printStackTrace();
thrownewRuntimeException();
}
}
@Override
public String[] getParameterValues(String name) {
return getParameterMap().get(name);
}
@Override
public String getParameter(String name) {
String[] values =getParameterValues(name);
return values == null ? null : values[0];
}
}
/**
* 过滤方法
*/
publicvoid doFilter(final ServletRequest request, ServletResponse response,FilterChainchain) throws IOException,ServletException {
//解决乱码
//响应乱码
response.setContentType("text/html;charset="+encode);
//请求参数
ServletRequest myRequest= newMyServletRequest((HttpServletRequest) request);
//资源放行
chain.doFilter(myRequest,response);
}
/**
* 销毁方法
*/
publicvoid destroy() {
}
}