1.Servlet是什么?
Servlet是Java Web三大组件之一,它属于动态资源。Servlet的作用是处理请求,服务器会把接收到的请求交给Servlet来处理,在Servlet中通常需要:
- 接受数据请求
- 处理请求
- 完成响应
例如客户端发出登录请求,或者输入注册请求,这些请求都应该由Servlet来完成处理。当然Servlet类需要我们自己来编写,每个Servlet类都必须实现javax.servlet.Servlet接口。
2.实现Servlet的方式(需要我们自己来写)
- 实现javax.servlet.Servlet接口;
- 继承javax.servlet.GenericServlet类;
- 继承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了,哈哈!当然这是后话)。