1.ServletRequest能够被强转为HttpServletRequest的原因
首先,他们的继承结构为:
public interface HttpServletRequest extends ServletRequest
HttpServletRequest
是 ServletRequest
的子接口。
在 HTTP 协议环境下,Servlet 容器(如 Tomcat)传给 service()
方法的实际对象是 HttpServletRequest
的实现类
所以:传进来的是子类型,你用父类型接收,再向下转型回子类型,是合法的。
当在Filter中看到这个方法时:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
虽然参数类型是 ServletRequest
,但在 HTTP 请求场景下,实际传入的对象并不是一个普通的 ServletRequest
,而是 实现了 HttpServletRequest
接口的具体类的实例。
所以可以安全的向下转型:
HttpServletRequest httpRequest = (HttpServletRequest) request;
2.为什么设计成ServletRequest
而不是直接用 HttpServletRequest
为了解耦和扩展性:
ServletRequest
是通用接口,适用于任何协议(目前主要是HTTP)
如果将来支持 FTPServlet
或 WebSocketServlet
,也可以使用 ServletRequest
。
但你在处理 HTTP 请求时,就需要使用 HttpServletRequest
提供的特有方法,比如:
getMethod()
:获取请求方法(GET、POST)getHeader()
:获取请求头getSession()
:获取会话getCookies()
:获取 Cookie
这些方法只有 HttpServletRequest
有,ServletRequest
没有。