关于Filter中ServletRequest和ServletResponse强转HttpServletRequest和HttpServletResponse
---转载自:https://www.cnblogs.com/mei0619/p/8341159.html
request对象的生成方式不是ServletRequest request = new ServletRequest();这种形式,而是ServletRequest request = new HttpServletRequest();
为什么在Filter里要强制转换?
答:ServletRequest request;这个是将子类对象赋给父类引用,他运行时的类型是子类,编译时的类型是父类,但是在运行时,父类类型对象调用的方法如果子类里面有,那就执行子类里面的方法,如果编译时的类型也就是父类没有调用的那个方法,则报错。所以在那里要做一个强制类型转换,否则就会报错。
HttpServletRequest比ServletRequest多了一些针对于Http协议的方法.如getHeader (String name), getMethod () ,getSession () 等等..
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
}
因为要用到HttpServletRequest中的方法,我对ServletRequest进行了强转,然后问题解决。可是后来一想不对啊,我们知道我们对子类实现进行向上转型得到父类对象是安全的,因为子类会完全继承父类的方法,我们向上转型为父类,当我们调用父类的方法其实在子类实现中是能完全找到的。反之向下转型是不安全的,我们子类除了完全继承父类的方法外还会拓展自己的方法,所以我们在调用子类方法时可能在父类实现中是找不到的,所以向下转型不安全。
可是本例中的实现却让我们困惑,我们不仅实现了向下转型,同时还调用了子类拓展的方法,是父类没有的,可是却实现了。这不是和我们所学矛盾吗?后来看了API和一些资料我终于明白了,这和我们所学其实并不冲突!我们先看API:
public interface HttpServletRequest extends ServletRequest
终于找到原因了,原来HttpServletRequest和ServletRequest都是接口,他们都只是定义了方法却没有提供相关实现。所以我们看到的ServletRequest request中的request对象其实并不是我们ServletRequest 的一个具体实现。
这里我们要看我们提出的问题是否安全,其实主要看request 对象的具体实现类究竟是继承的哪个接口,如果继承自HttpServletRequest接口那么我们向下转型使用HttpServletRequest接口的方法就是安全的。测试如下:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if(request instanceof HttpServletRequest){
System.out.println("-------------");
}
HttpServletRequest req = (HttpServletRequest) request;
if(req instanceof HttpServletRequest){
System.out.println("我是右边类的实例");
}
HttpServletResponse resp = (HttpServletResponse) response;
}
输出:
-------------
我是右边类的实例
证明我们的request对象的确是HttpServletRequest的一个实例。
也就是说doFilter的参数request对象的生成方式不是ServletRequest request = new ServletRequest();这种形式,而是ServletRequest request = new HttpServletRequest();这种形式,参数里的request不是父类ServletRequest的对象,而是HttpServletRequest的上转型对象:
根据《java面向对象程序设计(第2版)》,一个父类类型的对象如果是用子类new出来的时候(ServletRequest request = new HttpServletRequest();//就是这行代码), 就不能称之为父类对象,而是一个子类的上转型对象。这两者是有区别的,区别的其中一点就是父类对象不可强制转换为子类对象,而子类的上转型对象可以强制转换回子类对象。
再说一下为什么在Filter里要强制转换?
答:ServletRequest request;这个是将子类对象赋给父类引用,他运行时的类型是子类,编译时的类型是父类,但是在运行时,父类类型对象调用的方法如果子类里面有,那就执行子类里面的方法,如果编译时的类型也就是父类没有调用的那个方法,则报错。所以在那里要做一个强制类型转换,否则就会报错。
HttpServletRequest比ServletRequest多了一些针对于Http协议的方法.如getHeader (String name), getMethod () ,getSession () 等等..
疑问解决。
关于Filter中ServletRequest和ServletResponse强转HttpServletRequest和HttpServletResponse的更多相关文章
- 关于Filter中ServletRequest和ServletResponse强转HttpServletRequest和HttpServletResponse安全问题(向下转型一定不安全吗?)
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOE ...
- 关于Filter中ServletRequest强转HttpServletRequest问题
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOE ...
- Servlet的生命周期及filter,servletRequest和servletResponse
序,Web应用中,Servlet和Filter是很重要的两个概念,一定要理解透彻. 一.Servlet类 继承自HttpServlet,HttpServlet是一个抽象类,主要包含的方法有init,s ...
- javaWEB中的ServletRequest,ServletResponse的使用,及简化Servlet方法
首先说一下ServletRequest,ServletResponse类的使用方法: public void service(ServletRequest request, ServletRespon ...
- Filter中request对象强转问题
以下为过滤器doFIlter方法的源代码: public void doFilter(ServletRequest request, ServletResponse response, FilterC ...
- 在Java filter中调用service层方法
在项目中遇到一个问题,在 Filter中注入 Serivce失败,注入的service始终为null.如下所示: public class WeiXinFilter implements Filter ...
- 两种include方式及filter中的dispatcher解析
两种include方式 我自己写了一个original.jsp,另外有一个includedPage.jsp,我想在original.jsp中把includedPage.jsp引进来有两种方式: 1.& ...
- 如何在Java Filter 中注入 Service
在项目中遇到一个问题,在 Filter中注入 Serivce失败,注入的service始终为null.如下所示: public class WeiXinFilter implements Filter ...
- java 过滤器Filter中chain.doFilter()之前和之后代码的执行顺序
过滤器拦截到响应url的请求后会先执行doFilter()方法中chain.doFilter()之前的代码,然后执行下一个过滤器或者servelt.紧接着执行chain.doFilter()之后的代码 ...
随机推荐
- 最短路(Dijkstra) HDOJ 4318 Power transmission
题目传送门 题意:起点s到终点t送电,中途会有损耗,问最小损耗是多少 分析:可以转换为单源最短路问题,用优先队列的Dijkstra版本,d[]表示从s出发到当前点的最小损耗,用res保存剩下的电量.当 ...
- DEV—【GridControl主从表】
先附上效果图,不是想要这个效果的朋友就不用可以继续寻找了. DEV—GridControl制作主从表: (注:此例没有用到数据库,只是单纯的在内存中操作数据.) 写这一笔,是为了能更好的理解主从表,的 ...
- $.extend(x,y); 函数用法介绍。
第一篇资料: 转自: https://www.cnblogs.com/yuqingfamily/p/5813650.html 语法:jQuery.extend( [deep ], target, o ...
- actuator服务实战
1. actuator服务实战 1.1. 前言 actuator默认集成了很多端点查看,这里我会挑选也用到可能性大些的 1.2. Endpoints 1.2.1. 使用方式 开启服务后,直接访问:lo ...
- 文档兼容性定义,使ie按指定的版本解析
作为开发人员,特别是作为Web的前端开发人员 ,最悲催的莫过于要不断的,不断的去调试各种浏览器的显示效果,而这其中最让人头痛的莫过于MS下的IE系列浏览器,在IE系列中的调试我们将会发现没有一个是好伺 ...
- asterisk-java ami5 分机状态,挂机原因之类的
这些东西网上随便一找一大堆,也只是记录下自己找的.方便以后自己复制粘贴用. 最后为啦实现分机状态在web的实时更新,我选择啦使用websocket. //获得分机状态 public static St ...
- Beta冲刺提交-星期五
Beta冲刺提交-星期五 这个作业属于哪个课程 软件工程 这个作业要求在哪里 <作业要求的链接> 团队名称 唱跳RAP编程 这个作业的目标 1.进行每日例会,每个成员汇报自己今天完成 ...
- CE工具里自带的学习工具--第三关
图解: 重复第5,6,7,8,9步,最终得到:
- vc中无符号字符数组保存的内存值转换为无符号整数保存
分为三步,第一步,将进行指针类型转换:第二步,进行*地址运算:第三部赋值. 贴代码如下: unsigned char numberPlain [4] = {0}; UINT32 MaxNumber = ...
- Duplicate fragment name ERROR Jetty Maven Plugin
http://stackoverflow.com/questions/5802096/duplicate-fragment-name-error-jetty-maven-plugin 4down vo ...