1.8 GenericServlet抽象类

1.8 GenericServlet

通过实现Servlet接口方式来编写Servlet,你必须实现Servlet接口之中的所有方法,即便其中有一些方法是根本就没有包含任何代码的空方法。此外,还需要将ServletConfig对象保存到类级变量中。值得庆幸的是**GenericServlet抽象类的出现。本着尽可能使代码简单的原则,GenericServlet实现了ServletServletConfig接口**,并完成以下任务:
-将init方法中的ServletConfig赋给一个类级变量,以便可以通过调用getServletConfig获取。
-为Servlet接口中的所有方法提供默认的实现。
-提供方法,包围ServletConfig中的方法。

GenericServlet通过将ServletConfig赋给init方法中的servletConfig这个类级变量,来保存ServletConfig。下面就是GenericServlet中的init实现:

1
2
3
4
5
6
public void init(ServletConfig servletConfig) 
throws ServletException
{
this.servletConfig = servletConfig;
this.init();
}

Servlet中的init方法,并且还必须调用super.init(servletConfig)来保存ServletConfig。为了避免上述麻烦,**GenericServlet提供了第二个init方法**,它不带参数。这个方法是在ServletConfig被赋给servletConfig后,由第一个init方法调用:

1
2
3
4
5
6
public void init(ServletConfig servletConfig) 
throws ServletException
{
this.servletConfig = servletConfig;
this.init();
}

这意味着,可以通过覆盖没有参数的init方法来编写初始化代码,ServletConfig则仍然由GenericServlet实例保存。下面的GenericServletDemoServlet类是对之前的ServletConfigDemoServlet类的改写。注意,这个新的Servlet扩展(继承)了GenericServlet,而不是实现Servlet

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package app01a;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.GenericServlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
@WebServlet(
name = "GenericServletDemoServlet",
urlPatterns =
{"/generic"},
initParams =
{@WebInitParam(
name = "admin",
value = "Harry Taciak"
),@WebInitParam(
name = "email",
value = "admin@example.com"
)}
)
public class GenericServletDemoServlet
extends GenericServlet
{
private static final long serialVersionUID = 62500890L;
//只需要覆盖用用到的方法即可
@Override
public void service(ServletRequest request,
ServletResponse response)
throws ServletException,IOException
{
ServletConfig servletConfig = getServletConfig();
String admin = servletConfig.getInitParameter("admin");
String email = servletConfig.getInitParameter("email");
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.print("<html><head></head><body>" +
"Admin:" + admin
+ "<br/>Email:" + email + "</body></html>");
}
}

可见,通过扩展(继承)GenericServlet方式编写的Servlet,不需要覆盖那些没计划要改变的方法。因此,代码变得更加整洁。在上述代码中,唯一被覆盖的方法是service方法。而且不必手动保存ServletConfig。 利用下面这个URL调用Servlet,其结果应该与 ServletConfigDemoServlet相似:
http://localhost:8080/Hello/generic
即使
GenericServlet是对Servlet一个很好的加强,但它也不常用
,因为它毕竟不像HttpServlet那么高级。**HttpServlet才是主角,在现实的应用程序中被广泛使用**。关于它的详情,请查阅1.9节。