解读Servlet原理篇二---GenericServlet与HttpServlet
编程技术  /  houtizong 发布于 3年前   198
在上一篇《解读Servlet原理篇一》中提到,要实现javax.servlet.Servlet接口(即写自己的Servlet应用),你可以写一个继承自javax.servlet.GenericServletr的generic Servlet ,也可以写一个继承自java.servlet.http.HttpServlet的HTTP Servlet(这就是为什么我们自定义的Servlet通常是extentds HttpServlet的)。
那GenericServlet和HttpServlet的区别是什么,如何使用这两个类呢?
Servlet API中是这样描述GenericServlet的:
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.
简译之,GenericServlet定义了一个通用的,无关协议的的Servlet。如果要在Web应用中使用Http进行Servlet通信,请扩展HttpServlet(即继承HttpServlet)。
package javax.servlet;import java.io.IOException;import java.io.Serializable;import java.util.Enumeration;public abstract class GenericServlet implements Servlet, ServletConfig,Serializable {private transient ServletConfig config;public void destroy() {}public String getInitParameter(String name) {return getServletConfig().getInitParameter(name);}public Enumeration getInitParameterNames() {return getServletConfig().getInitParameterNames();}public ServletConfig getServletConfig() {return this.config;}public ServletContext getServletContext() {return getServletConfig().getServletContext();}public String getServletInfo() {return "";}public void init(ServletConfig config) throws ServletException {this.config = config;init();}public void init() throws ServletException {}public void log(String msg) {getServletContext().log(getServletName() + ": " + msg);}public void log(String message, Throwable t) {getServletContext().log(getServletName() + ": " + message, t);}public abstract void service(ServletRequest paramServletRequest,ServletResponse paramServletResponse) throws ServletException,IOException;public String getServletName() {return this.config.getServletName();}}
需要注意的点:
package javax.servlet.http;import java.io.IOException;import java.io.Serializable;import java.lang.reflect.Method;import java.text.MessageFormat;import java.util.Enumeration;import java.util.ResourceBundle;import javax.servlet.GenericServlet;import javax.servlet.ServletException;import javax.servlet.ServletOutputStream;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;public abstract class HttpServlet extends GenericServlet implementsSerializable {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 ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.http.LocalStrings");protected long getLastModified(HttpServletRequest req) {return -1L;}protected void doHead(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {NoBodyResponse response = new NoBodyResponse(resp);doGet(req, response);response.setContentLength();}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(405, msg);elseresp.sendError(400, msg);}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(405, msg);elseresp.sendError(400, msg);}protected void doPut(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {String protocol = req.getProtocol();String msg = lStrings.getString("http.method_put_not_supported");if (protocol.endsWith("1.1"))resp.sendError(405, msg);elseresp.sendError(400, msg);}protected void doDelete(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {String protocol = req.getProtocol();String msg = lStrings.getString("http.method_delete_not_supported");if (protocol.endsWith("1.1"))resp.sendError(405, msg);elseresp.sendError(400, msg);}private static Method[] getAllDeclaredMethods(Class c) {if (c.equals(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;}protected void doOptions(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {Method[] methods = getAllDeclaredMethods(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 == null))allow = "GET";if (ALLOW_HEAD)if (allow == null)allow = "HEAD";elseallow = allow + ", HEAD";if (ALLOW_POST)if (allow == null)allow = "POST";elseallow = allow + ", POST";if (ALLOW_PUT)if (allow == null)allow = "PUT";elseallow = allow + ", PUT";if (ALLOW_DELETE)if (allow == null)allow = "DELETE";elseallow = allow + ", DELETE";if (ALLOW_TRACE)if (allow == null)allow = "TRACE";elseallow = allow + ", TRACE";if (ALLOW_OPTIONS) {if (allow == null)allow = "OPTIONS";elseallow = allow + ", OPTIONS";}resp.setHeader("Allow", allow);}protected void doTrace(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {String CRLF = "\r\n";String responseString = "TRACE " + req.getRequestURI() + " "+ req.getProtocol();Enumeration reqHeaderEnum = req.getHeaderNames();while (reqHeaderEnum.hasMoreElements()) {String headerName = (String) reqHeaderEnum.nextElement();responseString = responseString + CRLF + headerName + ": "+ req.getHeader(headerName);}responseString = responseString + CRLF;int responseLength = responseString.length();resp.setContentType("message/http");resp.setContentLength(responseLength);ServletOutputStream out = resp.getOutputStream();out.print(responseString);out.close();}protected void service(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {String method = req.getMethod();if (method.equals("GET")) {long lastModified = getLastModified(req);if (lastModified == -1L) {doGet(req, resp);} else {long ifModifiedSince = req.getDateHeader("If-Modified-Since");if (ifModifiedSince < lastModified / 1000L * 1000L) {maybeSetLastModified(resp, lastModified);doGet(req, resp);} else {resp.setStatus(304);}}} else if (method.equals("HEAD")) {long lastModified = getLastModified(req);maybeSetLastModified(resp, lastModified);doHead(req, resp);} else if (method.equals("POST")) {doPost(req, resp);} else if (method.equals("PUT")) {doPut(req, resp);} else if (method.equals("DELETE")) {doDelete(req, resp);} else if (method.equals("OPTIONS")) {doOptions(req, resp);} else if (method.equals("TRACE")) {doTrace(req, resp);} else {String errMsg = lStrings.getString("http.method_not_implemented");Object[] errArgs = new Object[1];errArgs[0] = method;errMsg = MessageFormat.format(errMsg, errArgs);resp.sendError(501, errMsg);}}private void maybeSetLastModified(HttpServletResponse resp,long lastModified) {if (resp.containsHeader("Last-Modified"))return;if (lastModified >= 0L)resp.setDateHeader("Last-Modified", lastModified);}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);}}
需要注意的点:
Http协议方法 | HttpServlet实现方法 |
OPTIONS | doOption() |
GET | doGet() |
POST | doPost() |
TRACE | doTrace() |
PUT | doPut() |
DELETE | doDelete() |
参考资料:
http://www.codejava.net/java-ee/servlet/servlet-api-overview
http://www.uml-diagrams.org/examples/java-servlet-25-api-package-diagram-example.html
https://tomcat.apache.org/tomcat-5.5-doc/servletapi/
https://tomcat.apache.org/tomcat-5.5-doc/servletapi/
http://jzinfo.iteye.com/blog/502581
http://mavforcezt1008.iteye.com/blog/1222966
http://www.itzhai.com/tomcat-source-code-analysis-httpservlet-source-code-analysis.html
请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!
技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成
网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];
文章归档
文章标签
友情链接