10008---servlet源码(Servlet Interface 、GenericSerlvet Abstract Class、HttpServlet Class)
1、public interface ServletDefines methods that all servlets must implement.A servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clie
Defines methods that all servlets must implement.
A servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol.
To implement this interface, you can write a generic servlet that extends javax.servlet.GenericServlet or an HTTP servlet that extends javax.servlet.http.HttpServlet.
This interface defines methods to initialize a servlet, to service requests, and to remove a servlet from the server. These are known as life-cycle methods and are called in the following sequence:
1.The servlet is constructed, then initialized with the init method.
2.Any calls from clients to the service method are handled.
3.The servlet is taken out of service, then destroyed with the destroy method, then garbage collected and finalized.
In addition to the life-cycle methods, this interface provides the getServletConfig method, which the servlet can use to get any startup information, and the getServletInfo method, which allows the servlet to return basic information about itself, such as author, version, and copyright.
javax.servlet.servlet接口源码:
- package
javax.servlet; //Tomcat源码版本:6.0.20 - import
java.io.IOException; -
- public
interface Servlet { -
-
- //负责初始化Servlet对象。容器一旦创建好Servlet对象后,就调用此方法来初始化Servlet对象
-
public void init(ServletConfig config) throws ServletException; -
-
-
-
//方法负责响应客户的请求,提供服务。当容器接收到客户端要求访问特定的servlet请求时,就会调用Servlet的service方法 -
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException; -
-
-
-
public void destroy(); -
-
-
-
-
-
-
public String getServletInfo(); -
-
-
public ServletConfig getServletConfig(); - }
2、
同时,HttpServlet这个抽象类继承了GenericServlet抽象类,在Http协议上提供了通用的实现。
API:
Defines a generic, protocol-independent servlet. To write an HTTP servlet for use on the Web, extend HttpServlet instead.
GenericServlet implements the Servlet and ServletConfig interfaces. GenericServlet may be directly extended by a servlet, although it's more common to extend a protocol-specific subclass such as HttpServlet.
GenericServlet makes writing servlets easier. It provides simple versions of the lifecycle methods init and destroy and of the methods in the ServletConfig interface. GenericServlet also implements the log method, declared in the ServletContext interface.
To write a generic servlet, you need only override the abstract service method.
查看GenericSerlvet抽象类源码:
- package
javax.servlet; -
- import
java.io.IOException; - import
java.util.Enumeration; -
- //抽象类GenericServlet实现了Servlet接口的同时,也实现了ServletConfig接口和Serializable这两个接口
- public
abstract class GenericServlet -
implements Servlet, ServletConfig, java.io.Serializable - {
-
//私有变量,保存 init()传入的ServletConfig对象的引用 -
private transient ServletConfig config; -
-
//无参的构造方法 -
public GenericServlet() { } -
-
-
-
-
-
-
-
public void init(ServletConfig config) throws ServletException { -
this.config = config; -
this.init(); //调用了无参的 init()方法 -
} -
-
//无参的init()方法 -
public void init() throws ServletException { -
-
} -
-
-
//空实现了destroy方法 -
public void destroy() { } -
-
-
//实现了接口中的getServletConfig方法,返回ServletConfig对象 -
public ServletConfig getServletConfig() -
{ -
return config; -
} -
-
//该方法实现接口<Servlet>中的ServletInfo,默认返回空字符串 -
public String getServletInfo() { -
return ""; -
} -
-
-
//唯一没有实现的抽象方法service(),仅仅在此声明。交由子类去实现具体的应用 -
//在后来的HttpServlet抽象类中,针对当前基于Http协议的Web开发,HttpServlet抽象类具体实现了这个方法 -
//若有其他的协议,直接继承本类后实现相关协议即可,具有很强的扩展性 -
-
public abstract void service(ServletRequest req, ServletResponse res) -
throws ServletException, IOException; -
-
-
-
-
-
-
-
-
-
-
-
//该方法实现了接口<ServletConfig>中的getServletContext方法,用于返回servleConfig对象中所包含的servletContext方法 -
public ServletContext getServletContext() { -
return getServletConfig().getServletContext(); -
} -
-
//获取初始化参数 -
public String getInitParameter(String name) { -
return getServletConfig().getInitParameter(name); -
} -
-
//实现了接口<ServletConfig>中的方法,用于返回在web.xml文件中为servlet所配置的全部的初始化参数的值 -
public Enumeration getInitParameterNames() { -
return getServletConfig().getInitParameterNames(); -
-
//获取在web.xml文件中注册的当前的这个servlet名称。没有在web.xml 中注册的servlet,该方法直接放回该servlet的类名。 -
//法实现了接口<ServleConfig>中的getServletName方法 -
public String getServletName() { -
return config.getServletName(); -
} -
-
-
-
-
public void log(String msg) { -
getServletContext().log(getServletName() + ": " +msg); -
} -
-
-
public void log(String message, Throwable t) { -
getServletContext().log(getServletName() + ": " + message, t); -
} - }
3、HttpServlet是继承了GenericServlet抽象类的一个抽象类,但是他的里面并没有任何抽象方法,这就是说他并不会强迫我们去做什么。我们只是按需选择,重写HttpServlet中的的部分方法就可以了。
API:
Provides an abstract class to be subclassed to create an HTTP servlet suitable for a Web site. A subclass of HttpServlet must override at least one method, usually one of these:
•doGet, if the servlet supports HTTP GET requests
•doPost, for HTTP POST requests
•doPut, for HTTP PUT requests
•doDelete, for HTTP DELETE requests
•init and destroy, to manage resources that are held for the life of the servlet
•getServletInfo, which the servlet uses to provide information about itself
There's almost no reason to override the service method. service handles standard HTTP requests by dispatching them to the handler methods for each HTTP request type (the doXXX methods listed above).
Likewise, there's almost no reason to override the doOptions and doTrace methods.
Servlets typically run on multithreaded servers, so be aware that a servlet must handle concurrent requests and be careful to synchronize access to shared resources. Shared resources include in-memory data such as instance or class variables and external objects such as files, database connections, and network connections. See the Java Tutorial on Multithreaded Programming for more information on handling multiple threads in a Java program.
下面是抽象类HttpServlet的源码:
- package
javax.servlet.http; - .....
//节约篇幅,省略导入包 -
- public
abstract class HttpServlet extends GenericServlet -
implements java.io.Serializable - {
-
-
private static final String METHOD_GET = "GET"; -
private static final String METHOD_POST = "POST"; -
...... -
-
-
-
public HttpServlet() { } -
-
-
-
-
-
//doXXXX方法开始 -
protected void doGet(HttpServletRequest req, HttpServletResponse resp) -
throws ServletException, IOException -
{ -
String protocol = req.getProtocol(); -
String msg = lStrings.getString("http.method_get_not_supported"); -
if (protocol.endsWith("1.1")) { -
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg); -
} else { -
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg); -
} -
} -
-
-
protected void doHead(HttpServletRequest req, HttpServletResponse resp) -
throws ServletException, IOException -
{ -
....... -
} -
protected void doPost(HttpServletRequest req, HttpServletResponse resp) -
throws ServletException, IOException -
{ -
String protocol = req.getProtocol(); -
String msg = lStrings.getString("http.method_post_not_supported"); -
if (protocol.endsWith("1.1")) { -
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg); -
} else { -
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg); -
} -
} -
protected void doPut(HttpServletRequest req, HttpServletResponse resp) -
throws ServletException, IOException { -
//todo -
} -
-
-
protected void doOptions(HttpServletRequest req, HttpServletResponse resp) -
throws ServletException, IOException { -
//todo -
} -
-
protected void doTrace(HttpServletRequest req, HttpServletResponse resp) -
throws ServletException, IOException { -
//todo -
} -
-
protected void doDelete(HttpServletRequest req, -
HttpServletResponse resp) -
throws ServletException, IOException { -
//todo -
} -
//doXXXX方法结束 -
-
-
-
//重载的service(args0,args1)方法 -
protected void service(HttpServletRequest req, HttpServletResponse resp) -
throws ServletException, IOException -
{ -
String method = req.getMethod(); -
-
if (method.equals(METHOD_GET)) { -
long lastModified = getLastModified(req); -
if (lastModified == -1) { -
// servlet doesn't support if-modified-since, no reason -
// to go through further expensive logic -
doGet(req, resp); -
} else { -
long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE); -
if (ifModifiedSince < (lastModified / 1000 * 1000)) { -
// If the servlet mod time is later, call doGet() -
// Round down to the nearest second for a proper compare -
// A ifModifiedSince of -1 will always be less -
maybeSetLastModified(resp, lastModified); -
doGet(req, resp); -
} else { -
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); -
} -
} -
-
} else if (method.equals(METHOD_HEAD)) { -
long lastModified = getLastModified(req); -
maybeSetLastModified(resp, lastModified); -
doHead(req, resp); -
-
} else if (method.equals(METHOD_POST)) { -
doPost(req, resp); -
-
} else if (method.equals(METHOD_PUT)) { -
doPut(req, resp); -
-
} else if (method.equals(METHOD_DELETE)) { -
doDelete(req, resp); -
-
} else if (method.equals(METHOD_OPTIONS)) { -
doOptions(req,resp); -
-
} else if (method.equals(METHOD_TRACE)) { -
doTrace(req,resp); -
-
} else { -
// -
// Note that this means NO servlet supports whatever -
// method was requested, anywhere on this server. -
// -
-
String errMsg = lStrings.getString("http.method_not_implemented"); -
Object[] errArgs = new Object[1]; -
errArgs[0] = method; -
errMsg = MessageFormat.format(errMsg, errArgs); -
-
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg); -
} -
} -
-
-
//实现父类的service(ServletRequest req,ServletResponse res)方法 -
//通过参数的向下转型,然后调用重载的service(HttpservletRequest,HttpServletResponse)方法 -
-
public void service(ServletRequest req, ServletResponse res) -
throws ServletException, IOException -
{ -
HttpServletRequest request; -
HttpServletResponse response; -
-
try { -
request = (HttpServletRequest) req; //向下转型 -
response = (HttpServletResponse) res; //参数向下转型 -
} catch (ClassCastException e) { -
throw new ServletException("non-HTTP request );or response" -
} -
service(request, response); //调用重载的service()方法 -
} -
-
......//其他方法 - }
值得一说的是,很多介绍servlet的书中,讲解servlet第一个实例时候,都习惯去覆盖HttpServlet的service(HttpServletRequest request,HttpServletResponse response)方法来演示servlet.
当然,直接覆盖sevice()方法,作为演示,可以达到目的。因为servlet首先响应的就是调用service()方法,直接在此方法中覆盖没问题。但在实际的开发中,我们只是根据请求的类型,覆盖响应的doXXX方法即可。最常见的是doGet和doPost方法。
从HtttpServlet的源码中关于service()
更多推荐
所有评论(0)