7

我对doGet(),doPost()和其他HttpServlet类方法的访问修饰符感到困惑。

他们为什么protected

根据我的理解,protected修饰符doGet()意味着客户端必须在同一个包中(或通过继承的子包)才能访问doGet(). 那么调用 JSP 或容器将如何访问它呢?

4

6 回答 6

11

它们受到保护主要有两个原因。

  1. 这样外部类就不能像您所推理的那样只调用它们。从技术上讲,有一些方法可以使用 Java Reflection 绕过方法可见性修饰符(如果安全管理器允许或没有),但通常情况下,受保护的方法只能由同一包中的类或子类访问,这让我到第 2 点。
  2. 这样子类或具体实现HttpServlet可以覆盖它们。好吧,如果它们是公开的,它们也可以被覆盖,但请参阅第 1 点。

现在您的另一个问题是,“那么调用 JSP 或容器将如何访问它?”

HttpServlet实现Servlet接口,该接口声明了一个service(ServletRequest, ServletResponse)方法。当然,默认情况下会变成publicin HttpServlet。这是调用实现的主要入口点(对于容器)HttpServlet

我的猜测(我没有深入研究源代码)是HttpServlet检查ServletRequest传入的对象的默认实现,这实际上是一个HttpServletRequest并且定义了一个getMethod()返回所使用的 HTTP 方法的方法。doGet()然后它根据 HTTP 请求方法或doPost()根据 HTTP 请求方法进行分派。

于 2013-01-28T06:34:41.237 回答
3

这是来自官方的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。

于 2013-01-28T06:11:09.413 回答
2

doGet 和 doPost 是生成 HttpResponse 并将其发送到客户端(即通常是 Browser 或 HttpClient)的基本方法

此外,容器调用的Servlet.service()方法是public. 然后它调用HttpServlet.service()受保护的方法,然后调用doGet()/doPost()方法。

于 2013-01-28T06:12:17.547 回答
1

假设我有一个MyClass不是 servlet 的类,那么我是否希望我的类有方法doGetdoPost?好吧,如果它不是一个 servlet,那么它如何响应或捕获任何基于 Web 的请求。

只有 servlet 可以捕获和响应基于 Web 的请求。

因此,只有当我的类扩展时,我才能捕获和响应基于 Web 的请求是有道理的,Servlet因此我将能够使用doGet,doPost和各种其他方法。

于 2013-01-28T06:09:55.553 回答
0

我想您想知道 servlet 容器如何调用受保护的方法 doGet 和 doPost。

实际上有一个名为javax.servlet.Servlet的接口。一个名为GenericServlet的类实现了该接口。HTTPServlet 类扩展了这个 GenericServlet。

当有一个对 HTTPServlet 的 http 请求时,容器只需使用接口中声明的方法 service(...)。该方法是公开的。然后在GenericServlet 中,服务方法调用doGet 和doPost。如果你的 servlet 类扩展了 HTTPServlet 类并覆盖了 doPost 方法,那么这个方法最终会被调用。

于 2013-01-28T06:20:33.803 回答
0

protected其视为覆盖方法的邀请。您正在从中派生一个类,HttpServlet因此这些方法是要覆盖的方法。它们都有一个默认操作,因此您可以覆盖您的应用程序感兴趣的方法。

于 2013-01-28T06:24:10.587 回答