28
2020
04

添加Servlet构造函数出现的问题及解决方法

我们需要用到servlet的时候,都是右键,新建一个servlet,但是有人注意到一个细节没有,当我们手动给我们的servlet添加一个构造函数时候,会出现什么状况呢?

1.尝试添加无参构造函数

直接上代码

public class Test extends HttpServlet {

    Test(String a){
        System.out.println("这是构造函数");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

好了,一个我们都熟悉的基本的servlet,它的名字叫做Test。

为了方便起见,我们重写接口Servlet中的init()函数,并配置这个Servlet预加载,更直观的帮助我们理解。

public class Test extends HttpServlet {
    Test(){
        System.out.println("这是构造函数");
    }
    @Override
    public void init() throws ServletException {
        System.out.println("这是Init函数");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

好了,关于预加载,简单说,就是服务器运行的的时候,就会实例化这个servlet并且走完init()函数,这样,我们只需开启服务器,不需要进行请求,就可以看出这个servlet'是否被正确实例化。

好了,测试开始,启动服务器。

实验结果:手动写的Test()构造函数没有被执行,init()函数也没被执行。浏览器访问此Servlet时,404错误。

实验结论:当我们手动一个无参Servlet构造函数时,服务器就不会创建我们请求的servlet实例,当然也不会走servlet的生命周期

2.尝试有参构造函数

public class Test extends HttpServlet {

    Test(String a){
        System.out.println("这是构造函数");
    }

    @Override
    public void init() throws ServletException {
        System.out.println("这是Init函数");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

结果同无参构造函数一样:服务器不会创建servlet实例。

3.web.xml给出错误提示

错误说,我们的servlet没有默认的构造函数。

我们现在证明了,手动写一个有参和无参构造函数后,服务器都不会创建这个实例,根据xml错误,我们保留默认无参构造函数,并重载一个有参构造函数

public class Test extends HttpServlet {

    Test(){}

    Test(String a){
        System.out.println("这是构造函数");
    }

    @Override
    public void init() throws ServletException {
        System.out.println("这是Init函数");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

实验结果:构造函数仍无法输出任何内容,init()方法也不输出,说明servlet仍未被创建实例。

4.结果猜想:我们都知道,当我们请求servlet时候,服务器会根据servlet的servlet-class,反射创建servlet对象,并且会将一切参数传入到实例中(例如request,response,servletConfig等),

大致流程就是Class.from("我们的servlet-class").getDeclaredConstructor(上述说的参数类型...).newInstance(上述说的参数的值...)

因为,只有这样构造实例,才能把一些必要的数据(request,response,servletConfig),封装到实例里面。

况且,这个有参构造函数,第一句又调用了无参构造函数,也就是 this();

这样,通过有参构造函数将参数传递过来并保存,然后在无参构造函数中,进行初始化servlet,因此,当我们重写了无参构造,服务器就无法完成这些流程,因此,服务器直接做一个判断,如果你手动写了构造函数,直接让这个servlet无法初始化。

原文链接:https://www.qiquanji.com/post/7647.html

本站声明:网站内容来源于网络,如有侵权,请联系我们,我们将及时处理。

gzh

微信扫码关注

更新实时通知

« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。