动态代理解决编码问题

1.设计模式

出现原因:软件开发过程中,遇到相似问题,将问题的解决方法抽取模型(套路)

常见设计模式:单例,工厂,适配器,装饰者,动态代理。

2.装饰者模式简单介绍

谷歌汽车开发场景

1.Java定义了汽车开发约定

interface ICar{start , run , stop}
calss GooleCar implements ICar{}

2.目的:将谷歌Car接入导生态平台时,增强汽车功能

3.问题:谷歌Car的代码无法获取,且无法继承,不能直接操作其源码

装饰者模式

场景:在二次开发时,无法获取源码,且不能被继承的情况下,对以存在对象上的功能进行增强。

前提:可以获取被装饰的对象的所有实现接口

实现思路:自定义对象继承被装饰对象的接口,为自定义装饰类传递被装饰的对象

装饰者模式的弊端

如果被实现的接口中方法过的,则其所有方法都要被重写,装饰类会显得冗杂。

3.动态代理

解决装饰者模式的弊端

a.原理

通过虚拟机在内存创建类似MyCar.Class文件

要创建MyCar.Class文件来告诉虚拟机:

​ 1.被创建的字节码文件上需要哪些方法

字节码加载器

jdk有一些程序专业将各种字节码文件加载到内存,这类程序称为字节码加载器

如何将字节码文件class文件加载到内存?

底层提供IO技术,获取文件中的数据加载到内存。

字节码加载器有3种

public class TestClassLoader {
public static void main(String[] args) { //获取String类的加载器
ClassLoader classLoader = String.class.getClassLoader();
System.out.println(classLoader);
//由于String.class ,int.class等字节码文件需要频繁的被加载内存,速度必须快,底层用其他语言来实现c c++ //获取ext(extendtion)包下的某个类的字节码加载器 ExtClassLoader:扩展类加载器
ClassLoader classLoader2 = sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader();
System.out.println(classLoader2); //应用类:程序员实现的所有的类都属于应用类
//获取应用类加载器 AppClassLoader
ClassLoader classLoader3 = TestClassLoader.class.getClassLoader();
System.out.println(classLoader3);
}
}

动态代理简单案例

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays; public class TestCar {
public static void main(String[] args) { //1param: 固定值: 告诉虚拟机用哪个字节码加载器加载内存中创建出的字节码文件
//2param: 告诉虚拟机内存中正在被创建的字节码文件中应该有哪些方法
//3param: 告诉虚拟机正在被创建的字节码上的各个方法如何处理
ICar car=(ICar)Proxy.newProxyInstance(TestCar.class.getClassLoader(), GoogleCar.class.getInterfaces(),new InvocationHandler() { //method:代表正在执行的方法
//args:代表正在执行的方法中的参数
//Object:代表方法执行完毕之后的返回值
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//经过测试得知:method代表当前正在执行的每个方法
//System.out.println(method.getName());
//执行当前的方法
//method.invoke(new GoogleCar(), args); //代表每个方法执行完毕之后返回对象
Object obj=null; if(method.getName().equalsIgnoreCase("start")){
System.out.println("检查天气是否良好"); //打印args中的内容
System.out.println(Arrays.toString(args)); obj=method.invoke(new GoogleCar(), args);
System.out.println("检查路况是否拥堵"); }else{
obj=method.invoke(new GoogleCar(), args);
}
return obj;
}
});
String cc=car.start(1,4);
System.out.println(cc);
car.run();
car.stop();
}
} class MyCC implements InvocationHandler{
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
}

动态代理解决servlet的get请求的中文编码问题

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; public class EncodingFilter implements Filter { public EncodingFilter() {
} public void destroy() {
}
public void init(FilterConfig fConfig) throws ServletException {
} public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//将request对象转换为HttpServletRequest
final HttpServletRequest req=(HttpServletRequest)request;
//让JDK在内存中生成代理对象:增强了req对象上的getParameter(name);API
HttpServletRequest myReq=(HttpServletRequest)Proxy.newProxyInstance(EncodingFilter.class.getClassLoader(), req.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 md=req.getMethod();
if("get".equalsIgnoreCase(md)){
//get方式的请求
//调用req对象上的getParameter方法
String v=(String)method.invoke(req, args);
//转码
String vv=new String(v.getBytes("iso-8859-1"),"utf-8");
return vv; }else{
//post方式的请求
req.setCharacterEncoding("utf-8");
obj=method.invoke(req, args);
} }else{
obj=method.invoke(req, args);
}
return obj;
}
});
//打印代理对象哈希码
System.out.println(myReq.hashCode());
//将代理对象放行
chain.doFilter(myReq, response);
}
}

JavaWeb之动态代理解决request请求编码问题的更多相关文章

  1. 二十二 动态代理&解决网站的字符集编码问题

    设计模式: 软件开发过程中,遇到相似问题,将问题的解决方式抽取模型(套路) 单例,工厂,装饰者,适配器,动态代理 谷歌汽车场景: 谷歌汽车场景Car Interface Icar{  start  r ...

  2. 自定义HttpReqeust,解决request请求参数只能拿一次就失效的问题

    定义一个过滤器并实现如下方法 @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResp ...

  3. Java动态代理实现及实际应用

    一.代理的概念 动态代理技术是整个java技术中最重要的一个技术,它是学习java框架的基础,不会动态代理技术,那么在学习Spring这些框架时是只知应用不懂实现. 动态代理技术就是用来产生一个对象的 ...

  4. Java动态代理的两种实现方法

    注:文章转载自:https://blog.csdn.net/m0_38039437/article/details/77970633 一.代理的概念 动态代理技术是整个java技术中最重要的一个技术, ...

  5. java中Proxy(代理与动态代理)

    转自: https://blog.csdn.net/pangqiandou/article/details/52964066 一.代理的概念 动态代理技术是整个java技术中最重要的一个技术,它是学习 ...

  6. Java提高班(六)反射和动态代理(JDK Proxy和Cglib)

    反射和动态代理放有一定的相关性,但单纯的说动态代理是由反射机制实现的,其实是不够全面不准确的,动态代理是一种功能行为,而它的实现方法有很多.要怎么理解以上这句话,请看下文. 一.反射 反射机制是 Ja ...

  7. JDK 原生动态代理是怎么实现的 + 面试题

    JDK 原生动态代理是怎么实现的 + 面试题 反射 反射机制是 Java 语言提供的一种基础功能,赋予程序在运行时自省(introspect)的能力.简单来说就是通过反射,可以在运行期间获取.检测和调 ...

  8. Java动态代理与Cglib库

    JDK动态代理 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在 ...

  9. JDK动态代理与Cglib库

    JDK动态代理 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在 ...

随机推荐

  1. Python 从入门到进阶之路(五)

    之前的文章我们简单介绍了一下 Python 的函数,本篇文章我们来看一下 Python 中的面向对象. Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是 ...

  2. netty源码解析(4.0)-21 ByteBuf的设计原理

        io.netty.buffer包中是netty ByteBuf的实现.ByteBuf是一个二进制缓冲区的抽象接口,它的功能有: 可以随机访问.顺序访问. 支持基本数据类型(byte, shor ...

  3. Kubernetes的CronJob对象

    CronJob说白了就是用来管理Job对象的控制器, 通过jobTemplate管理Job对象,定时执行,最终实现我们的cron功能 示例 apiVersion: batch/v1beta1 kind ...

  4. 原生PHP网页导出和导入excel文件实例

    原生PHP实现的网页导出和导入excel文件实例,包括上传也是用的原生.还可在exportExcel方法里设置字体等表格样式. 导出和导入表单代码: <p style="margin: ...

  5. Java集合专题

    1.Java 中常用的容器有哪些? 常见容器主要包括 Collection 和 Map 两种,Collection 存储着对象的集合,而 Map 存储着键值对(两个对象)的映射表. Collectio ...

  6. SpringCloud(二):服务的注册与发现(Eureka)

    一.什么是服务注册与发现Spring Cloud Eureka 模块提供的功能是被动式的服务发现. 服务注册:每个用户去聊天室服务器上注册. 服务发现:这样他的好友们就能看到你,你同时也将获取好友的上 ...

  7. [browser srceen]、很多未知望大神告知、简单写了个拖拽

    未知作用的有.如果也有像我1样好奇的小伙伴了解了麻烦告知 // console.log(window.screen.availWidth);//未知效果 // console.log(window.s ...

  8. wireshark和tcpdump抓包TCP乱序和重传怎么办?PCAP TCP排序工具分享

    点击上方↑↑↑蓝字[协议分析与还原]关注我们 " 介绍TCP排序方法,分享一个Windows版的TCP排序工具." 在分析协议的过程中,不可避免地需要抓包. 无论抓包条件如何优越, ...

  9. SAP MM 供应商无英文名称,ME21N里却带出了英文名字?

    SAP MM 供应商无英文名称,ME21N里却带出了英文名字? 近日收到客户业务用户上报的一个问题说ME21N的时候,供应商101071的名字怎么是英文名字,实际上供应商主数据里是没有这个英文名字, ...

  10. Android App图片资源文件压缩利器McImage

    版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/195 Android App图片资源文件压缩利器McIma ...