1.  GenericServlet 抽象类:

    1). 是一个 Serlvet. 是 Servlet 接口和 ServletConfig 接口的实现类. 但是一个抽象类. 其中的 service 方法为抽象方法

    2). 如果新建的 Servlet 程序直接继承 GenericSerlvet 会使开发更简洁.

    3). 具体实现:

       ①. 在 GenericServlet 中声明了一个 SerlvetConfig 类型的成员变量, 在 init(ServletConfig) 方法中对其进行了初始化

       ②. 利用 servletConfig 成员变量的方法实现了 ServletConfig 接口的方法

         ③. 还定义了一个 init() 方法, 在 init(SerlvetConfig) 方法中对其进行调用, 子类可以直接覆盖 init() 在其中实现对 Servlet 的初始化.

       ④. 不建议直接覆盖 init(ServletConfig), 因为如果忘记编写 super.init(ServletConfig); 而还是用了 SerlvetConfig 接口的方法,则会出现空指针异常.

       ⑤. 新建的 init(){} 并非 Serlvet 的生命周期方法. 而 init(ServletConfig) 是生命周期相关的方法.

     注:为什么添加一个无参的init()方法?相信你有JavaSE的基础就会明白了!在此就不在赘述了,如果你不知道你可以去看一下关于方法的重载、方法的重写、类与父        类的关系之super的用法。

 GenericServlet的源码:

 public abstract class GenericServletimplements Servlet, ServletConfig, java.io.Serializable{

 private transient ServletConfig config;

     public GenericServlet() { }
/**
* 下面的方法是实现Servlet接口中的方法。
*/
public void destroy() {
} public ServletConfig getServletConfig() {
return config;
} public String getServletInfo() {
return "";
} public abstract void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException; public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
} public void init() throws ServletException { } /**
* 下面的方法是实现ServletConfig接口中的方法。
*/ public String getInitParameter(String name) {
return getServletConfig().getInitParameter(name);
} public Enumeration getInitParameterNames() {
return getServletConfig().getInitParameterNames();
} public ServletContext getServletContext() {
return getServletConfig().getServletContext();
} public String getServletName() {
return config.getServletName();
} public void log(String msg) {
getServletContext().log(getServletName() + ": "+ msg);
}
/**
* 下面的方法是GenericServlet抽象类自己定义的方法。
*/ public void log(String message, Throwable t) {
getServletContext().log(getServletName() + ": " + message, t);
}
}

2.  HttpServlet 抽象类:

   1). 是一个 Servlet, 继承自 GenericServlet. 针对于 HTTP 协议所定制.

   2). 在service(ServletRequest, ServletResponse) 方法中直接把 ServletReuqest和ServletResponse 转为 HttpServletRequest 和 HttpServletResponse.并调用了重载的 service(HttpServletRequest, HttpServletResponse)方法,在 重载的 service(HttpServletRequest, HttpServletResponse) 获取了请求方式: request.getMethod(). 根据请求方式有创建了doXxx() 方法(xxx 为具体的请求方式, 比如 Get, Post等等方式。)

HttpServlet源码:

 public abstract class HttpServlet extends GenericServlet
implements java.io.Serializable { 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(LSTRING_FILE);
public HttpServlet() { } 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 long getLastModified(HttpServletRequest req) {
return -1;
} 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(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, 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(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, 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(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
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;
}
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)
if (allow==null) 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);
}
protected void doTrace(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{ int responseLength; String CRLF = "\r\n";
String responseString = "TRACE "+ req.getRequestURI()+
" " + req.getProtocol(); Enumeration reqHeaderEnum = req.getHeaderNames(); while( reqHeaderEnum.hasMoreElements() ) {
String headerName = (String)reqHeaderEnum.nextElement();
responseString += CRLF + headerName + ": " +
req.getHeader(headerName);
} responseString += CRLF; responseLength = responseString.length(); resp.setContentType("message/http");
resp.setContentLength(responseLength);
ServletOutputStream out = resp.getOutputStream();
out.print(responseString);
out.close();
return;
} 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);
}
}
private void maybeSetLastModified(HttpServletResponse resp,
long lastModified) {
if (resp.containsHeader(HEADER_LASTMOD))
return;
if (lastModified >= 0)
resp.setDateHeader(HEADER_LASTMOD, 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);
}
} /*
* A response wrapper for use in (dumb) "HEAD" support.
* This just swallows that body, counting the bytes in order to set
* the content length appropriately. All other methods delegate to the
* wrapped HTTP Servlet Response object.
*/
// file private
class NoBodyResponse extends HttpServletResponseWrapper {
private NoBodyOutputStream noBody;
private PrintWriter writer;
private boolean didSetContentLength; // file private
NoBodyResponse(HttpServletResponse r) {
super(r);
noBody = new NoBodyOutputStream();
} // file private
void setContentLength() {
if (!didSetContentLength)
super.setContentLength(noBody.getContentLength());
} // SERVLET RESPONSE interface methods public void setContentLength(int len) {
super.setContentLength(len);
didSetContentLength = true;
} public ServletOutputStream getOutputStream() throws IOException {
return noBody;
} public PrintWriter getWriter() throws UnsupportedEncodingException { if (writer == null) {
OutputStreamWriter w; w = new OutputStreamWriter(noBody, getCharacterEncoding());
writer = new PrintWriter(w);
}
return writer;
}
} /*
* Servlet output stream that gobbles up all its data.
*/ // file private
class NoBodyOutputStream extends ServletOutputStream { private static final String LSTRING_FILE =
"javax.servlet.http.LocalStrings";
private static ResourceBundle lStrings =
ResourceBundle.getBundle(LSTRING_FILE); private int contentLength = 0; // file private
NoBodyOutputStream() {} // file private
int getContentLength() {
return contentLength;
} public void write(int b) {
contentLength++;
} public void write(byte buf[], int offset, int len)
throws IOException
{
if (len >= 0) {
contentLength += len;
} else {
// XXX
// isn't this really an IllegalArgumentException? String msg = lStrings.getString("err.io.negativelength");
throw new IOException(msg);
}
}
}

    3). 实际开发中, 直接继承 HttpServlet, 并根据请求方式复写 doXxx() 方法即可.

    4). 优点: 直接由针对性的覆盖 doXxx() 方法; 直接使用 HttpServletRequest 和  HttpServletResponse, 不再需要强转.

JavaWeb学习笔记之Servlet(二)的更多相关文章

  1. JavaWeb学习笔记之Servlet(一)

    1. 引子: 当我们开始进入JavaWeb开发的学习时,我们就必须要和Servlet和HTTP这两个词进行打交道了,尤其是Servlet.即使到了后面使用JSP (我们知道JSP其本身就是一个Serv ...

  2. JavaWeb学习笔记三 Servlet

    Servlet 是运行在服务端的Java小程序,是sun公司提供一套规范(接口),用来处理客户端请求.响应给浏览器的动态资源.但servlet的实质就是java代码,通过java的API,动态的向客户 ...

  3. Javaweb学习笔记——(十二)——————JSP指令:page指令、include指令、taglib指令,JavaBean,内省,EL表达式

    JSP指令JSP指令分类 JSP有三大指令: *page指令 *include指令 *taglib指令 在JSP中没有任何指令是必须的. 但基本上每个JSP都是使用page指令============ ...

  4. JavaWeb学习笔记:Servlet

    Servlet JavaWeb 概念 Java Web应用由一组Servlet.HTML页面.类.以及其他能够被绑定的资源构成. 他能够在各种供应商提供的实现Servlet规范的Servlet容器中执 ...

  5. JavaWeb学习笔记(十二)—— JDBC的基本使用

    一.JDBC概述 1.1 数据库驱动 这里的驱动的概念和平时听到的那种驱动的概念是一样的,比如平时购买的声卡,网卡直接插到计算机上面是不能用的,必须要安装相应的驱动程序之后才能够使用声卡和网卡,同样道 ...

  6. JavaWeb学习笔记总结 目录篇

    JavaWeb学习笔记一: XML解析 JavaWeb学习笔记二 Http协议和Tomcat服务器 JavaWeb学习笔记三 Servlet JavaWeb学习笔记四 request&resp ...

  7. Java学习笔记之---Servlet

    Java学习笔记之---Servlet (一)如何实现Servlet 1.实现javax.servlet.Servlet接口: 2.继承javax.servlet.GenericServlet类: 3 ...

  8. javaweb学习笔记整理补课

    javaweb学习笔记整理补课 * JavaWeb: * 使用Java语言开发基于互联网的项目 * 软件架构: 1. C/S: Client/Server 客户端/服务器端 * 在用户本地有一个客户端 ...

  9. 【Unity Shaders】学习笔记——SurfaceShader(二)两个结构体和CG类型

    [Unity Shaders]学习笔记——SurfaceShader(二)两个结构体和CG类型 转载请注明出处:http://www.cnblogs.com/-867259206/p/5596698. ...

随机推荐

  1. Swift中使用构建配置来支持条件编译-b

    在Objective-C中,我们经常使用预处理指令来帮助我们根据不同的平台执行不同的代码,以让我们的代码支持不同的平台,如: 1 2 3 4 5 6 7 8 9 #if TARGET_OS_IPHON ...

  2. 记 tower.im 的一次重构

    原文in here: http://outofmemory.cn/wr?u=http%3A%2F%2Fblog.mycolorway.com%2F2013%2F05%2F01%2Ftower-refa ...

  3. 兼容各浏览器中的PNG透明效果CSS定义

    <style>.mycls{width: 48px;height: 48px;background: url(20090318230119136.png) no-repeat left t ...

  4. Growing Pains for Deep Learning

    Growing Pains for Deep Learning Advances in theory and computer hardware have allowed neural network ...

  5. 14.2 InnoDB and the ACID Model

    14.2 InnoDB and the ACID Model ACID 模型是一组数据库设计原则,强调可靠性方面对于商业数据和关键人物. MySQL 包含组件比如InnoDB存储引擎坚持ACID 模型 ...

  6. POJ1321 棋盘问题(dfs)

    题目链接. 分析: 用 dfs 一行一行的搜索,col记录当前列是否已经放置. AC代码如下: #include <iostream> #include <cstdio> #i ...

  7. -_-#【Angular】依赖注入

    AngularJS学习笔记 var BoxCtrl = function($scope, $element) { } var str = BoxCtrl.toString().replace(/\s/ ...

  8. HTML5 Web socket和socket.io

    what is websockets Two-way communication over ont TCP socket, a type of PUSH technology HTML5的新特性,用于 ...

  9. 声明 && 温馨提示 by ljh2000

    听说有人很喜欢狙我......看我不把你们抓起来嘿嘿嘿! 为了采取措施,不让被狙成为生活常态(雾   ,我要闭关锁国辣,我要开始屯田辣! 以后写完题目先存一波草稿,等屯题屯到10-20道时再一起发出来 ...

  10. Robot Framework selenium2library 常用关键字

    Selenium Library SeleniumLibrary is a Robot Framework test library that uses the popular Selenium we ...