Java Web中实现Servlet的方式

1.Servlet是什么?

Servlet是Java Web三大组件之一,它属于动态资源。Servlet的作用是处理请求,服务器会把接收到的请求交给Servlet来处理,在Servlet中通常需要:

  • 接受数据请求
  • 处理请求
  • 完成响应

例如客户端发出登录请求,或者输入注册请求,这些请求都应该由Servlet来完成处理。当然Servlet类需要我们自己来编写,每个Servlet类都必须实现javax.servlet.Servlet接口。

2.实现Servlet的方式(需要我们自己来写)

  1. 实现javax.servlet.Servlet接口;
  2. 继承javax.servlet.GenericServlet类;
  3. 继承javax.servlet.http.HttpServlet类;

一般来说我们都选择实现HttpServlet类来完成我们的Servlet,但学习Servlet还要从javax.servlet.Servlet接口来学起。

2.1实现javax.servlet.Servlet接口

实现该接口的代码如下,需要实现该接口中的5个方法(各个方法的作用见注释)。

其中只有三个生命周期的方法是由服务器(例如我用的Tomcat)在认为需要调用的时候自动调用的(即我们自己是无法调用的),另外的两个方法由我们自己需要的时候调用。

2.2继承javax.servlet.GenericServlet类

有人会说,那我每次实现Servlet接口都要重写这5个方法岂不是很麻烦?那肯定麻烦!所以GenericServlet类派上用场了。

GenericServlet类实现了Servlet接口,所以在GenericServlet类中实现了Servlet接口中的5个抽象方法,另外在GenerecServlet类中还定义了自己的方法,将其作为我们要定义的xxxServlet类的父类,这样我们在自己定义的xxxServlet类中便可以不用全部实现Servlet接口中的方法。

GenericServlet类中的方法如下:

由图可知,GenericServlet类除了实现Servlet接口中的四个方法外,还定义了getInitParameter()返回Servlet的参数值、getInitParameterNames()返回Servlet的参数名、getServletName()返回Servlet名、getServletContext()返回Servlet上下文、不带参数的init()、log()等方法。这些自己定义的方法中,前面四个是ServletConfig接口中的方法,不带参数的init()方法跟Servlet接口中的init(ServletConfig config)方法要区别,在init()方法中,我们可以添加当xxxServlet被初始化的操作,此方法在初始化方法init(ServletConfig config)中被调用(若是文字解析看不懂见下图GenericServlet源代码中注释)。

另外不知道你们发现了没有,图中只有service()方法属于抽象方法,所以当我们定义的xxxServlet类去继承GenericServlet类时我们只需重写这一个方法即可,其他方法可重写可不重写。

另外附上GenericServlet类的源代码:

代码中的xxxServlet类即是我们自己定义的servlet类。

扩展:对ServletContext的解释:

服务器会为每个应用创建一个ServletContext对象,一个应用只有一个ServletContext对象!我们可以在N多个Servlet中来获取这个唯一的对象,使用它可以给多个Servlet传递数据。此对象在Tomcat(服务器)启动时就创建,在服务器关闭时就销毁。

ServletContext是Java Web四大域对象(PageContext、ServletRequest、HttpSession、ServletContext)之一,域对象所具有的特点是:

  • 能够存数据
  • 能够取数据

所有的域对象都有存取数据的功能,因为域对象内部有一个Map,用来存储数据,下面是ServletContext对象用来操作数据的方法:

扩展:Servlet类三大域:

  • request:在Servlet中直接用,因为实现的doPost()方法中有request这个参数。
  • session:在Servlet中通过HttpSession session=request.getSession();得到。
  • application:在Servlet中通过ServletContext application=this.getServletContext();得到。

扩展:JSP中四大域

  • page域:即9大内置对象中的pageContext,为PageContext的实例。注意:“page域”不同于9大内置对象中“page”。
  • request域:即9大内置对象中的request,为HttpServletRequest的实例。
  • session域:即9大内置对象中的session,为HttpSession的实例。
  • application:即9大内置对象中的ServletContext的实例。

2.3.继承HttpServlet类

HttpServlet类是我们用到次数最多的,也是最简单的。由类名可知,该类总是跟http协议相关的。

HttpServlet类中的方法如下图:

方法中值得我们注意的有doGet()、doPost()、还有两个service()方法。其中doGet()和doPost()方法是需要我们重写的,我来解释下两个service()方法的区别。

估计你们从方法中的参数就知道他们的区别了吧,其中一个service()方法是Serlvet接口中的生命周期方法,另外一个是跟http协议有关的方法。二者方法的解释见下两站图的说明(图1中指出HttpServlet类是继承自GenderServlet类):

uml(时序图)如下:

图中405的含义是说服务器不支持客户端(即浏览器)用此种方法访问。因为HttpServlet类的源代码中的doGet()和doPost()方法体里面就是这样写的,你在定义的xxxservlet中如果不重新重写这两个方法就会出现405的响应状态码。接下来我们看看如何继承HttpServlet类:

FServlet即为我们自己定义的servlet类,在doGet()方法和doPost()方法中即可写具体要进行的操作。

如上三种方式便可实现我们自己定义的Servlet类,但实际开发中我们只需要使用第三种方式即继承HttpServlet类完成我们的自定义xxxServlet就好(另外等学了SSM框架中的Spring MVC框架后,就用不着我们再这样实现Servlet了,哈哈!当然这是后话)。

2018.3.19更

欢迎加入我的Java交流1群:659957958。

2018.4.21更:如果群1已满或者无法加入,请加Java学习交流2群:305335626

3.联系

If you have some questions after you see this article,you can tell your doubts in the comments area or you can find some info by clicking these links.

坚持原创技术分享,您的支持将鼓励我继续创作!