当我们每次写后端代码的时候往往会出现中文乱码问题,Post修改的方式又和Get不同,每次写代码的时候还都得带上修改字符集的代码,那么我们用动态代理就可以完美的解决字符集问题,每次写代码时就不用再改变字符集啦
主要思想很简单,就是利用过滤器和利用JDK的Proxy.newProxyInstance方法实现动态代理,反射是一切框架的基础,因此也会用到反射。
还是老规矩上来先说一下实现原理,毕竟原理是最重要的嘛
学了过滤器就感觉很好用,感觉生活中用过滤器的地方还挺多的
比如微信和qq的屏蔽功能
检测并处理王者荣耀啊什么的游戏一类的防止言语侮辱和一些禁用词汇等一些东西,自我感觉也是过滤器实现的
哪么这个思路也特简单
1.利用request找到获取前台参数的方法(getParamater),没有的话放行,有的话执行下面操作
method.getName().equalsIgnoreCase("getParameter")
2.判断是get方法还是post方法,并修改对应的字符编码
String m = request.getMethod();//request必须要是HttpServltRequest类型,因为只有这个方法才会有get和post之分
if ("get".equalsIgnoreCase(m)) //用if判断
然后放行,起到原来方法的修饰作用。
有人说啊这也可以用装饰者实现啊,或者可以直接给上边加代码为什么还要写这么多代码呢?
装饰者模式实现它的话需要实现的类太多了导致代码会看起来特别混乱
直接加代码也简单粗暴还能解决问题,但是如果代码多了每个都要写是不是就很麻烦了
package filter;
import com.sun.deploy.net.HttpRequest;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//配置所有请求都要过滤
@WebFilter(filterName = "EncodingFilter", urlPatterns = "/*")
public class EncodingFilter implements Filter {
public void doFilter(ServletRequest req, final ServletResponse resp, final FilterChain chain) throws ServletException, IOException {
//在匿名内部类中调用的只能说final类型的
final HttpServletRequest request = (HttpServletRequest) req;
//返回request,使用JDK创建代理对象,d对request进行增强
final HttpServletRequest myreq = (HttpServletRequest);
//这个JDK的一个实现动态代理的方法
//第一个参数是类加载器,也就可以理解为加载本类
//第二个参数是需要实现的类的所有接口
//第三个参数是一个匿名内部类实现接口返回一个Object
Proxy.newProxyInstance(EncodingFilter.class.getClassLoader(), request.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object obj = null;
if (method.getName().equalsIgnoreCase("getParameter")) {
String m = request.getMethod();
if ("get".equalsIgnoreCase(m)) {
//执行
// String um=request.getParameter("username");和下边的方法对应,所有返回String
String s = (String) method.invoke(request, args);
// 改变get方法的字符集
obj = new String(s.getBytes("iso-8859-1"), "utf-8");
return obj;
} else {
// 改变post
request.setCharacterEncoding("UTF-8");
// 执行
obj = method.invoke(request, args);
}
/**
* 写代码的时候忘记写下边这个else闹出了不少麻烦,总不知道哪里错了,链接进去一片空白,因为
* 如果少了这段代码的话就把获取参数之外的方法都给拦截了,因此页面一片空白,不能粗心大意了哈
*/
}else {
obj = method.invoke(request,args);
}
return obj;
}
});
//此时的Hashcode和放行的页面相同,同一个对象
System.out.println(myreq.hashCode());
//放行
chain.doFilter(myreq, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
有什么不对的地方欢迎指出,不懂的地方可以再评论区交流。
一个小白的学习之路,今天又是什么都没干的一天明天要好好学习哦!