Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

手动添加Servlet构造函数出现的问题及猜想

刷书小将 2019-02-05 23:56:00 阅读数:128 评论数:0 点赞数:0 收藏数:0

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

 

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


直接上代码

public class Test extends HttpServlet {
Test(){
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.cnblogs.com/zh1996/p/10353351.html

编程之旅,人生之路,不止于编程,还有诗和远方。
阅代码原理,看框架知识,学企业实践;
赏诗词,读日记,踏人生之路,观世界之行;

支付宝红包,每日可领