我对doGet()
,doPost()
和其他HttpServlet
类方法的访问修饰符感到困惑。
他们为什么protected
?
根据我的理解,protected
修饰符doGet()
意味着客户端必须在同一个包中(或通过继承的子包)才能访问doGet()
. 那么调用 JSP 或容器将如何访问它呢?
我对doGet()
,doPost()
和其他HttpServlet
类方法的访问修饰符感到困惑。
他们为什么protected
?
根据我的理解,protected
修饰符doGet()
意味着客户端必须在同一个包中(或通过继承的子包)才能访问doGet()
. 那么调用 JSP 或容器将如何访问它呢?
它们受到保护主要有两个原因。
HttpServlet
可以覆盖它们。好吧,如果它们是公开的,它们也可以被覆盖,但请参阅第 1 点。现在您的另一个问题是,“那么调用 JSP 或容器将如何访问它?”
HttpServlet
实现Servlet
接口,该接口声明了一个service(ServletRequest, ServletResponse)方法。当然,默认情况下会变成public
in HttpServlet
。这是调用实现的主要入口点(对于容器)HttpServlet
。
我的猜测(我没有深入研究源代码)是HttpServlet
检查ServletRequest
传入的对象的默认实现,这实际上是一个HttpServletRequest
并且定义了一个getMethod()
返回所使用的 HTTP 方法的方法。doGet()
然后它根据 HTTP 请求方法或doPost()
根据 HTTP 请求方法进行分派。
这是来自官方的javadoc。
提供一个抽象类,以创建适合网站的 HTTP servlet。HttpServlet 的子类必须覆盖至少一种方法,通常是以下其中一种:
doGet,如果 servlet 支持 HTTP GET 请求
doPost,用于 HTTP POST 请求
doPut,用于 HTTP PUT 请求
doDelete,用于 HTTP DELETE 请求
init 和 destroy,用于管理 servlet 生命周期内持有的资源
getServletInfo,servlet 用来提供有关自身的信息
并且
几乎没有理由重写服务方法。服务通过将标准 HTTP 请求分派给每种 HTTP 请求类型的处理程序方法(上面列出的 doXXX 方法)来处理它们。
在doGet
方法的文档中:
由服务器调用(通过 service 方法)以允许 servlet 处理 GET 请求。
所以HttpServlet
是为继承而设计的,入口点是service
方法。因此doGet
受到保护以强制执行明确的 API。
doGet 和 doPost 是生成 HttpResponse 并将其发送到客户端(即通常是 Browser 或 HttpClient)的基本方法
此外,容器调用的Servlet.service()
方法是public
. 然后它调用HttpServlet.service()
受保护的方法,然后调用doGet()
/doPost()
方法。
假设我有一个MyClass
不是 servlet 的类,那么我是否希望我的类有方法doGet
和doPost
?好吧,如果它不是一个 servlet,那么它如何响应或捕获任何基于 Web 的请求。
只有 servlet 可以捕获和响应基于 Web 的请求。
因此,只有当我的类扩展时,我才能捕获和响应基于 Web 的请求是有道理的,Servlet
因此我将能够使用doGet
,doPost
和各种其他方法。
我想您想知道 servlet 容器如何调用受保护的方法 doGet 和 doPost。
实际上有一个名为javax.servlet.Servlet的接口。一个名为GenericServlet的类实现了该接口。HTTPServlet 类扩展了这个 GenericServlet。
当有一个对 HTTPServlet 的 http 请求时,容器只需使用接口中声明的方法 service(...)。该方法是公开的。然后在GenericServlet 中,服务方法调用doGet 和doPost。如果你的 servlet 类扩展了 HTTPServlet 类并覆盖了 doPost 方法,那么这个方法最终会被调用。
将protected
其视为覆盖方法的邀请。您正在从中派生一个类,HttpServlet
因此这些方法是要覆盖的方法。它们都有一个默认操作,因此您可以覆盖您的应用程序感兴趣的方法。