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强转HttpServletRequest问题的更多相关文章

  1. 关于Filter中ServletRequest和ServletResponse强转HttpServletRequest和HttpServletResponse安全问题(向下转型一定不安全吗?)

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOE ...

  2. 关于Filter中ServletRequest和ServletResponse强转HttpServletRequest和HttpServletResponse

    ---转载自:https://www.cnblogs.com/mei0619/p/8341159.html request对象的生成方式不是ServletRequest request = new S ...

  3. Filter中request对象强转问题

    以下为过滤器doFIlter方法的源代码: public void doFilter(ServletRequest request, ServletResponse response, FilterC ...

  4. 在Java filter中调用service层方法

    在项目中遇到一个问题,在 Filter中注入 Serivce失败,注入的service始终为null.如下所示: public class WeiXinFilter implements Filter ...

  5. 如何在Java Filter 中注入 Service

    在项目中遇到一个问题,在 Filter中注入 Serivce失败,注入的service始终为null.如下所示: public class WeiXinFilter implements Filter ...

  6. Filter中排除对指定URL的过滤

    1. 我们可以在web.xml中配置filter来对指定的URL进行过滤,进行一些特殊操作如权限验证等. <!– session过滤filter –> <filter> < ...

  7. 如何在自定义Filter中优雅的实现静态资源放行

            在javaweb开发中,过滤器Filter比较常用于类似登录的拦截等场景.但是,当过滤器的配置不当时就会把所有的请求都拦截,静态资源也会被拦截掉,导致静态页面加载不出来. 一般的解决方 ...

  8. 解决在Filter中读取Request中的流后,后续controller或restful接口中无法获取流的问题

    首先我们来描述一下在开发中遇到的问题,场景如下: 比如我们要拦截所有请求,获取请求中的某个参数,进行相应的逻辑处理:比如我要获取所有请求中的公共参数 token,clientVersion等等:这个时 ...

  9. Filter 中注入失败问题

    参考: https://www.cnblogs.com/digdeep/p/4770004.html?tvd https://www.cnblogs.com/EasonJim/p/7666009.ht ...

随机推荐

  1. Vertical-Align你应该知道的一切

    好,我们聊聊vertical-align.这个属性主要目的用于将相邻的文本与元素对齐.而实际上,verticle-algin可以在不同上下文中灵活地对齐元素,以及进行细粒度的控制,不必知道元素的大小. ...

  2. GoldenGate -- OGG EXTRACT进程 OGG-00446 报错

    -- :: INFO OGG- Positioning to (Thread ) Sequence , RBA , SCN 0.470706262. Source Context : SourceMo ...

  3. sql查询关于时间的一些汇总

    今天的所有数据:select * from 表名 where DateDiff(dd,datetime类型字段,getdate())=0 昨天的所有数据:select * from 表名 where ...

  4. linux 特殊命令(二)

    Netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics),masquerade 连接,多播成员 (Multicast Membershi ...

  5. UML类图介绍以及PlantUML使用方法

    类的UML表示方法 UML介绍 类图,是UML(统一建模语言)中用于描述"类"以及"类与类"之间的示意图.它形象的描述出了系统的结构,帮助人们理解系统. 类图是 ...

  6. C# 设计模式之 单例模式

    单例模式三种写法: 第一种最简单,但没有考虑线程安全,在多线程时可能会出问题,不过俺从没看过出错的现象,表鄙视我…… public class Singleton{    private static ...

  7. composer切换中国镜像

    替换 composer.lock 文件中的 https://files.phpcomposer.com/files/ 为 https://dl.laravel-china.org 命令行 compos ...

  8. [转]Javascript removeChild()删除节点及删除子节点的方法(同样适用于jq)

    Javascript removeChild()删除节点及删除子节点的方法 这篇文章主要介绍了Javascript removeChild()删除节点及删除子节点的方法的相关资料,需要的朋友可以参考下 ...

  9. Waltz of love

    Waltz of love Love me tenderly Love me softly Close your eyes,fling to the dangcing hall Follow your ...

  10. web頁面優化以及SEO

    轉載:https://blog.csdn.net/xustart7720/article/details/79960591 浏览器访问优化浏览器请求处理流程如下图: Etag:實體標籤.ETag是HT ...