Servlet Source code parsing: Servlet interface and its important subclasses, servlet Source Code

Source: Internet
Author: User

Servlet Source code parsing: Servlet interface and its important subclasses, servlet Source Code
Here, we will only explain the necessary Servlet, Session, Rrequest, and Response interfaces and their child classes in the Servlet specification. Other content such as websocket, el, jsp, filter, and listener will not be introduced. Zookeeper

Servlet is a Java-based, container-hosted web component used to generate dynamic content. Servlet interface is the core abstraction of Java Servlet API. First, let's look at its source code:

Public interface Servlet {/*** is called by the servlet container after the servlet container is instantiated to indicate that the servlet has been loaded, provide the service to the customer * @ param config * @ throws ServletException */public void init (ServletConfig config) throws ServletException;/*** returns a ServletConfig object, this object contains * Servlet initialization and startup parameters * @ return */public ServletConfig getServletConfig (); /*** user request response function * @ param req * @ param res * @ throws ServletException * @ throws IOException */public void service (ServletRequest req, ServletResponse res) throws ServletException, IOException;/*** return the servlet author, version, copyright, and other information * @ return */public String getServletInfo (); /*** call this function when the servlet container wants to destroy the servlet * @ return */public void destroy ();}

The Servlet interface defines a set of Servlet behavior. Next let's take a look at its subclass GenericServlet:

Public abstract class GenericServlet implements Servlet, ServletConfig, java. io. serializable {private static final long serialVersionUID = 1L; private transient ServletConfig config;/*** no behavior, all initialization operations are in the init function */public GenericServlet () {// NOOP} @ Override public void destroy () {// NOOP by default}/*** get Servlet initialization parameter */@ Override public String getInitParameter (String name) {return getServletConfig (). getInitParameter (name);}/*** get Servlet initialization parameter name */@ Override public Enumeration <String> getInitParameterNames () {return getServletConfig (). getInitParameterNames () ;}@ Override public ServletConfig getServletConfig () {return config;}/*** return the Servlet runtime context object */@ Override public ServletContext getServletContext () {return getServletConfig (). getServletContext ();}/*** the default information is an empty String */@ Override public String getServletInfo () {return "" ;}@ Override public void init (ServletConfig config) throws ServletException {this. config = config; this. init ();} public void init () throws ServletException {// NOOP by default}/*** record the log information in the servlet log file */public void log (String msg) {getServletContext (). log (getServletName () + ":" + msg);} public void log (String message, Throwable t) {getServletContext (). log (getServletName () + ":" + message, t) ;}@ Override public abstract void service (ServletRequest req, ServletResponse res) throws ServletException, IOException; @ Override public String getServletName () {return config. getServletName ();}}

The GenerticServlet abstract class does not actually do any specific work, but provides some convenient functions to obtain context, servlet parameters, and perform logging. I still don't see the appearance of Request and Response. Will this be mentioned in its subclass? Let's take a look at its subclass HttpServlet:

Public abstract class HttpServlet extends GenericServlet {private static final long serialVersionUID = 1L; private static final String METHOD_DELETE = "DELETE"; private static final String METHOD_HEAD = "HEAD "; private static final String METHOD_GET = "GET"; private static final String METHOD_OPTIONS = "OPTIONS"; private static final String METHOD_POST = "POST"; private static final String METHOD _ PUT = "PUT"; private static final String METHOD_TRACE = "TRACE"; private static final String HEADER_IFMODSINCE = "If-Modified-Since "; private static final String HEADER_LASTMOD = "Last-Modified"; private static final String LSTRING_FILE = "javax. servlet. http. localStrings "; private static final ResourceBundle lStrings = ResourceBundle. getBundle (LSTRING_FILE); public HttpServlet () {// NOOP }/*** To process http get requests, you must implement the specific logic, otherwise, the returned http error Message * @ param req * @ param resp * @ throws ServletException * @ throws IOException */protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// obtain protocol String protocol = req. getProtocol (); // GET http. the International String of method_get_not_supported String msg = lStrings. getString ("http. method_get_not_supported "); if (protocol. endsW Ith ("1.1") {// if it is HTTP/1.1, the 405 forbidden access method error resp is returned. sendError (HttpServletResponse. SC _METHOD_NOT_ALLOWED, msg);} else {// if it is not HTTP/1.1, the 400 Error request error resp is returned. sendError (HttpServletResponse. SC _BAD_REQUEST, msg) ;}/ *** get the last modified time * @ param req * @ return */protected long getLastModified (HttpServletRequest req) {return-1 ;} /*** process the http head Request * @ param req * @ param resp * @ throws ServletException * @ throws IOException */protected void doHead (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {if (DispatcherType. INCLUDE. equals (req. getDispatcherType () {// If DispatcherType is INCLUDE, it is treated as a GET request to process doGet (req, resp );} else {// otherwise encapsulate the response without BODY information and return it to the client NoBodyResponse response = new NoBodyResponse (resp); doGet (req, response); response. setContentLength () ;}}/*** process HTT P post request, @ see doGet * @ param req * @ param resp * @ throws ServletException * @ throws 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_ALLOW ED, msg);} else {resp. sendError (HttpServletResponse. SC _BAD_REQUEST, msg) ;}}/*** process HTTP PUT requests * @ param req * @ param resp * @ throws ServletException * @ throws IOException */protected void doPut (HttpServletRequest req, httpServletResponse resp) throws ServletException, IOException {String protocol = req. getProtocol (); String msg = lStrings. getString ("http. method_put_not_supported "); if (proto Col. endsWith ("1.1") {resp. sendError (HttpServletResponse. SC _METHOD_NOT_ALLOWED, msg);} else {resp. sendError (HttpServletResponse. SC _BAD_REQUEST, msg) ;}}/*** process HTTP DELETE requests * @ param req * @ param resp * @ throws ServletException * @ throws IOException */protected void doDelete (HttpServletRequest req, httpServletResponse resp) throws ServletException, IOException {String protocol = req. getProt Ocol (); String msg = lStrings. getString ("http. method_delete_not_supported "); if (protocol. endsWith ("1.1") {resp. sendError (HttpServletResponse. SC _METHOD_NOT_ALLOWED, msg);} else {resp. sendError (HttpServletResponse. SC _BAD_REQUEST, msg) ;}/ *** except javax. servlet. http. all Declaration methods for any Class c other than HttpServlet * @ param c * @ return */private static Method [] getAllDeclaredMethods (Class <?> C) {if (c. equals (javax. servlet. http. httpServlet. class) {return null;} Method [] parentMethods = getAllDeclaredMethods (c. getSuperclass (); Method [] thisMethods = c. getDeclaredMethods (); if (parentMethods! = Null) & (parentMethods. length> 0) {Method [] allMethods = new Method [parentMethods. length + thisMethods. length]; System. arraycopy (parentMethods, 0, allMethods, 0, parentMethods. length); System. arraycopy (thisMethods, 0, allMethods, parentMethods. length, thisMethods. length); thisMethods = allMethods;} return thisMethods;}/*** process http options requests */protected void doOptions (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Method [] methods = getAllDeclaredMethods (this. getClass (); boolean ALLOW_GET = false; boolean ALLOW_HEAD = false; boolean ALLOW_POST = false; boolean ALLOW_PUT = false; boolean ALLOW_DELETE = false; boolean ALLOW_TRACE = true; boolean ALLOW_OPTIONS = true; for (int I = 0; I <methods. length; I ++) {Method m = methods [I]; if (m. getName (). equals ("doGet") {ALLOW_GET = true; ALLOW_HEAD = true;} if (m. getName (). equals ("doPost") ALLOW_POST = true; if (m. getName (). equals ("doPut") ALLOW_PUT = true; if (m. getName (). equals ("doDelete") ALLOW_DELETE = true;} String allow = null; if (ALLOW_GET) allow = METHOD_GET; if (ALLOW_HEAD) if (allow = null) allow = METHOD_HEAD; else allow + = "," + METHOD_HEAD; if (ALLOW_POST) if (allow = null) allow = METHOD_POST; else allow + = "," + METHOD_POST; if (ALLOW_PUT) if (allow = null) allow = METHOD_PUT; else allow + = "," + METHOD_PUT; if (ALLOW_DELETE) if (allow = null) allow = METHOD_DELETE; else allow + = "," + METHOD_DELETE; if (ALLOW_TRACE) if (allow = null) allow = METHOD_TRACE; else allow + = "," + METHOD_TRACE; if (ALLOW_OPTIONS) if (allow = null) allow = METHOD_OPTIONS; else allow + = "," + METHOD_OPTIONS; resp. setHeader ("Allow", allow);}/*** process http trace requests */protected void doTrace (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {int responseLength; string CRLF = "\ r \ n"; StringBuilder buffer = new StringBuilder ("TRACE "). append (req. getRequestURI ()). append (""). append (req. getProtocol (); Enumeration <String> reqHeaderEnum = req. getHeaderNames (); while (reqHeaderEnum. hasMoreElements () {String headerName = reqHeaderEnum. nextElement (); buffer. append (CRLF ). append (headerName ). append (":"). append (req. getHeader (headerName);} buffer. append (CRLF); responseLength = buffer. length (); resp. setContentType ("message/http"); resp. setContentLength (responseLength); ServletOutputStream out = resp. getOutputStream (); out. print (buffer. toString (); out. close (); return;}/*** process the actual call function of the http request, it further calls the doGet and doPost Methods * @ param req * @ param resp * @ throws ServletException * @ throws IOException */protected void service (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// get the method parameter of http request, which is actually the String method = req corresponding to the method attribute in the form tag // of html. getMethod (); // if it is a GET request if (method. equals (METHOD_GET) {// get the last modified time long lastModified = getLastModified (req); if (lastModified =-1) {/** if the servlet does not support the if-modified-since attribute of the http request header *, continue to process **/doGet (req, resp );} else {// if this attribute long ifModifiedSince is supported; try {ifModifiedSince = req. getDateHeader (HEADER_IFMODSINCE);} catch (IllegalArgumentException iae) {// Invalid date header-proceed as if none was set ifModifiedSince =-1 ;} /*** if the last modification time of the client file is the same as the last modification time of the Server File, the system returns 304 without modifying the status. * In this way, the server does not return html, and the browser reads the local cache file, otherwise, obtain the corresponding html file */if (ifModifiedSince <(lastModified/1000*1000) {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 {// if the method attribute of the http header exceeds the range of get, head, post, put, delete, // options, and trace, the system returns 501. The request error String errMsg = lStrings is not supported.. 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) ;}} private void maybeSetLastModified (HttpServletResponse resp, long lastModified) {if (resp. containsHeader (HEADER_LASTMOD) return; if (lastModified> = 0) resp. setDateHeader (HEADER_LASTMOD, lastModified);}/*** overwrites the service method of the parent class. If the developer inherits this class, it is not necessary to implement this method, you only need to implement the service method */@ Override public void service (ServletRequest req, ServletResponse res) throws ServletException, IOException {HttpServletRequest request; incluresponse; try {request = (HttpServletRequest) req; response = (HttpServletResponse) res;} catch (ClassCastException e) {throw new ServletException ("non-HTTP request or response");} service (request, response );}}
HttpServlet has the specific implementation details of doService at the beginning, which makes the local cache file function of the browser really start to play a role, improving the HTTP access efficiency. The specific implementation details of doService must be


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.