H5W3
当前位置:H5W3 > 其他技术问题 > 正文

Java servlet中 service()方法的小疑问

在抽象类HttpServlet的源码中存在service()方法,
其中service()方法中也调用了doGet()方法;
        
现在我自定义一个继承了HttpServlet抽象类的servlet程序,覆盖了doGet()方法,
为什么在浏览器中访问的时候,调用的是我的doGet()方法,
而不是HttpServlet抽象类的doGet()方法

例如,下面的程序能否模拟 真正的servlet程序调用service()方法时的情景,
但下面的程序调用的却是HttpServlet类的doGet()方法

 应该去掉除main方法外的static修饰符,见后图

图片描述

图片描述

回答:

servlet 容器通过解析你的 http 请求路由找到对应的 servelt 对象即 yourHttpServlet, 因为这个对象继承了 HttpServlet 类所以就继承了 service()doGet()。当你覆盖了 doGet()yourHttpServlet 拥有的就是覆盖后的 doGet(),所以调用 yourHttpServlet.service() 就会调用 yourHttpServelt.doGet()没毛病啊。

—-针对你的问题修改后—-

你怎么都写成了静态(static)方法啊,静态方法的成员方法在类的继承中是有一些区别的,建议你在网上查查。针对你这个模拟主要是作用域不同,就是说静态方法的作用域是在类级别上的。

abstract class HttpServlet {
    public static void service() {
        doGet();    // 等价于 HttpServlet.doGet();
    }

    public static void doGet() {
        
    }
}

MyServlet 继承了 HttpServlet 后就继承了 service()doGet() ,但是这两个方法是静态的,所以不会被子类的方法覆盖(这是和成员方法的区别),即你在 MyServlet 中定义的 doGet() 是没有覆盖 HttpServlet 中的 doGet() 的。

myServlet.service()Myservlet.service() 效果是一样的,建议使用类去调研静态方法。这个 service() 调用的是 HttpServlet.doGet()。如果你想在里面调用 MyServletdoGet() 就要在该类里面重新定义 service()

你这种模拟是不对的,因为在真正的 HttpServlet 里的 service()doGet() 都不是静态的。

回答:

Web容器会读取你的web.xml,然后得到你的Servlet的位置,用Servlet对象来接收你的Servlet实例(大概是反射获得吧),Web容器只需调用Servlet接口里的方法,不管具体实现。实际上调用的是你复写的方法。

public interface Servlet
public interface ServletConfig 
public abstract class GenericServlet implements Servlet, ServletConfig
public abstract class HttpServlet extends GenericServlet

本文地址:H5W3 » Java servlet中 service()方法的小疑问

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址