动态代理技术在JavaWeb中的应用
来源:互联网 发布:中国知网数据库查重 编辑:程序博客网 时间:2024/06/05 15:32
(这是我的第五次反馈)
本次所上的内容是:
1.用动态代理技术解决全站乱码问题
2.用动态代理技术解决压缩输出问题
1.1用动态代理技术解决全站乱码问题思路
在这里我们用到了JavaWeb中的Filter技术
在以前我们在Filter中放行的时候所传的对象是HttpServletRequest和HttpServletResponse,通过这两个对象直接设置编码会解决全站的post请求的乱码
而单单靠这两个原始对象不能解决get请求的乱码
通过动态代理技术我们可以产生一个request的代理对象,通过这个代理对象中的方法可以对getParameter方法进行拦截
然后再将得到的数据进行手动转换
最后放行,解决全站乱码问题
核心代码如下:
package filter;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.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class CharacterEncodingFilter implements Filter{ @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { //解决了post请求下的乱码问题 final HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;character=UTF-8"); //在Filter放行之前我们要对request包装一把来对get请求拦截处理 chain.doFilter((ServletRequest) Proxy.newProxyInstance(CharacterEncodingFilter.class.getClassLoader(),request.getClass().getInterfaces(),new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(!method.getName().equals("getParameter")){ return method.invoke(request, args); } if(!request.getMethod().equalsIgnoreCase("get")){ return method.invoke(request, args); } //到了这里肯定就是get方法所带过来的数据 String value = (String) method.invoke(request, args);//手动转换 if(value == null){ return null; } return new String(value.getBytes("iso8859-1"),"UTF-8"); } }), response); } @Override public void init(FilterConfig arg0) throws ServletException { } @Override public void destroy() { }}
2.1解决压缩输出问题的思路
首先我们要压缩的数据是来自于服务器端的
servlet会通过response给客户机输出数据
而重点就是response会直接给客户机输出数据不会压缩之后输出数据
在此我们又用到了Filter(拦截器)对输出的数据进行拦截然后压缩打给客户机以减少流量
具体来说response输出数据的方式有两种 getWriter和getOutPutStream
其中getOutPutStream得到的对象自己没有带缓冲流所以我们先要new一个缓冲流对象
然后重写它的write方法,让数据写到我们所new的缓冲流对象中然后压缩输出给客户机
然后getWriter得到的对象自己带有缓冲流
所以我们用OutputStreamWriter作为桥梁来将数据写到我们自己的缓冲流中
最后一并压缩输出
具体的思路见代码
package filter;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.zip.GZIPOutputStream;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletOutputStream;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpServletResponseWrapper;public class GzipFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { final HttpServletRequest request = (HttpServletRequest) req; final HttpServletResponse response = (HttpServletResponse) res; final ByteArrayOutputStream bout = new ByteArrayOutputStream(); final PrintWriter pw = new PrintWriter(new OutputStreamWriter(bout,"UTF-8")); chain.doFilter(request, (ServletResponse) Proxy.newProxyInstance(GzipFilter.class.getClassLoader(),response.getClass().getInterfaces(),new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(method.getName().equalsIgnoreCase("getWriter")){ return pw; }else if(method.getName().equalsIgnoreCase("getOutPutStream")){ //返回我们的自定义流 return new MyOutputStream(bout); }else{ return null; } } })); pw.close();//让pw的数据释放确保都到了bout里面 byte[] result = bout.toByteArray();//让流中的数据还原到一个比特数组中准备压缩输出 System.out.println("原始大小:"+result.length); ByteArrayOutputStream bout2 = new ByteArrayOutputStream();//它是存储压缩后的数据的 GZIPOutputStream gzip = new GZIPOutputStream(bout2);//写到Bout的缓存里面 gzip.write(result);//这就是那个压缩过程 gzip.close();//保证写到了bout2里面 result = bout2.toByteArray();//bout2还原数据 System.out.println("压缩后的数据大小:"+result.length); response.setHeader("content-encoding","gzip"); response.setContentLength(result.length); response.getOutputStream().write(result); } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } @Override public void destroy() { // TODO Auto-generated method stub }}class MyOutputStream extends ServletOutputStream{ private ByteArrayOutputStream bout = new ByteArrayOutputStream(); public MyOutputStream(ByteArrayOutputStream bout) { this.bout = bout; } @Override public void write(int b) throws IOException { bout.write(b);//把数据写到这个字节数组中 }}
在此特别感谢方立勋老师!
阅读全文
1 0
- 动态代理技术在JavaWeb中的应用
- java3D技术在JavaWeb中的应用
- 理解动态代理及动态代理在RPC中的应用
- 动态代理在spring中的应用
- 动态代理在Spring AOP中的应用
- 动态代理及其在Spring中的应用
- 反射机制在代理中的应用(二) 动态代理
- Java中的动态代理技术
- 动态代理在mybatis接口式编程中的应用
- 动态代理在JDBC的DataSource中的应用
- JAVA的Proxy动态代理在自动化测试中的应用
- 【反射+注解+动态代理在事务中的应用service层】
- UEditor在JavaWeb中的应用
- UEditor在JavaWeb中的应用
- UEditor在JavaWeb中的应用
- 反射机制在代理中的应用(三) 动态代理中的反射机制
- 动态函数监控技术在缓冲区溢出检测中的应用
- AOP技术应用和研究--动态代理
- fluent nhibernate映射的数值类型问题
- SpringBoot-创建RESTful风格的 http接口访问jpa 来操作数据库
- spingMVC网页报“400”错误原因
- 沃顿商学院自我管理课
- HDU-6073 Matching In Multiplication(拓扑+dfs)
- 动态代理技术在JavaWeb中的应用
- 暑假多校联盟(=) e题 书架
- P3144 [USACO16OPEN]关闭农场Closing the Farm
- Python-栈
- web自动化测试第12步:selenium中下拉框的解决方法(Select)
- More is better HDU
- MySql主从同步和延迟同步
- 2017.8.4——。。。。。
- HTML第三天