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. 温故而知新 C++基本类型

    C++基本类型大小: 在32位计算机中测试得到:sizeof(bool) == 1sizeof(char) == 1 sizeof(short) == 2sizeof(int) == 4sizeof( ...

  2. 转载——web前端相关资源总结

    前端牛人博客:张克军.阮一峰.拔赤(李晶).拔赤(李晶)2.张鑫旭.梦想天空.阿当.泽飞.刘杰(嗷嗷).为之漫笔(李松峰).goddyzhao.hax的技术部落.周爱民.随网之舞.子鼠.司徒正美.ju ...

  3. Netbeans8下 Weblogic EJB案例

    1:接口 @Remote public interface XgmZzsNssb {} 2:实现 @Stateless(mappedName="XgmZzsNssbImpl") @ ...

  4. 【HDOJ】1348 Wall

    计算几何-凸包模板题目,Graham算法解. /* 1348 */ #include <iostream> #include <cstdio> #include <cst ...

  5. UVA253 Cube painting(数学)

    题目链接. 分析: 用的<训练指南>上的方法.详见P17. 从6个面中选一个做顶面,再从剩下的4个面中选1个做正面,则此正方体唯一确定. 需要枚举共6*4=24种. #include &l ...

  6. COJ 0986 WZJ的数据结构(负十四) 区间动态k大

    题解:哈哈哈我过了!!!主席树+树状数组写起来还真是hentai啊... 在这里必须分享我的一个沙茶错!!!看这段代码: void get(int x,int d){ ]=root[x];x;x-=x ...

  7. 【转】深层次探讨mutex与semaphore之间的区别(下)

    原文网址:http://blog.chinaunix.net/uid-23769728-id-3173282.html 这篇博文很长,虽然这是下篇,但还没结束,benchmark方面的东西正在进行中, ...

  8. 元素水平垂直居中(transform,margin,table-cell,jQuery)

    1.水平居中 .div{ margin:0 auto; (或者 margin:auto;) width:500px; height:300px; } 2.使用margin水平垂直居中 方式一: .di ...

  9. JDK 和JRE的区别

    JRE:Java Runtime Environment/Java运行时环境目标用户:只需要运行Java程序的用户JRE包含了:Deployment,User Interface Toolkits,I ...

  10. FSharp.Data 程序集之 Http

    FSharp.Data 程序集之 Http (** # F# Data: HTTP Utilities .NET 库提供了强大的 API,产生和发送 HTTP WEB 请求,有两个类型,一个简单,`W ...