提早聲明:我的說的不必定對,若有錯誤之處,請批評指出. html
servlet能夠很好地替代公共網關接口(Common Gateway Interface,CGI)腳本。一般CGI腳本是用Perl或者C語言編寫的,它們老是和特定的服務器平臺緊密相關。而servlet是用Java編寫的,因此它們一開始就是平臺無關的。這樣,Java編寫一次就能夠在任何平臺運行(write once,run anywhere)的承諾就一樣能夠在服務器上實現了。servlet還有一些CGI腳本所不具有的獨特優勢: java
但值得注意的是Servlet並不侷限於Web領域(或者說是HTTP協議相關).你可能要本身去擴展javax.servlet.GenericServlet .上面第三點就是這個意思.
好比說:擴展javax.servlet.GenericServlet實現一個Servlet,搞搞電子郵件的smtp(Simple Mail Transfer Protocol 即簡單郵件傳輸協議)服務器,你就是基於SMTP協議擴展了GenericServlet ,也許你會叫它SMTPServlet.咱們用的HttpServlet不就這個命名規範嘛.
綜上所述,Servlet能夠在各類協議下良好的運行應用程序. web
JSP的本質就是Servlet,或者說(是吧,開始說的是java,汗)JavaWeb開發的本質也就是Servlet+JDBC.任何性質的框架技術最底層的依然是基於他們2個.所以若是本身想寫一套如SSH那樣的框架技術,Java最底層的東西是必須掌握的. 數據庫
Servlet被稱爲"服務器端小程序."是運行在服務器端的程序,用於處理以及響應客戶端的請求. 編程
HTTP 目前支持 7 種請求方法: GET 、 POST 、 PUT 、 DELETE 和 TARCE,HEAD 、 OPTIONS .前四個都是客戶端請求數據這類相關的方法. 小程序
我在這裏只是列出HTTP的請求方法,具體的HTTP協議請參考這篇文章:http://my.oschina.net/zhaoqian/blog/90315 瀏覽器
Servlet是個特殊的類,這個類必須繼承HttpServlet.Servlet提供了相對於HTTP數據請求的四個方法的請求(其餘三個也提供了,但我懶得寫了,不多用到). 緩存
事實上,HTTP這個大好青年被浪費了,大部分咱們就是使用GET/POST請求,至於PUT/DELETE都不知道被遺棄到哪裏去了.但最近幾年興起的一種REST模型的WEB服務,讓HTTP協議發出了第二春.具體詳見:http://my.oschina.net/zhaoqian/blog/90321 安全
而諸如Struts2,SpringMVC這類的框架,也就是使用GET/POST,但工做時間久後,愈加的感受到,不少新技術,不必去追,所須要的是,搞清楚追底層的,以不變的底層去應對萬變的新技術. 服務器
Servlet的示例代碼:
package org.credo.test; import java.io.IOException; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * <P>Project: Credo's Base</P> * <P>Description:Servlet3.0的第一個測試. </P> * <P>Copyright (c) 2012 LionCredo.All Rights Reserved.</P> * @author <a href="zhaoqianjava@qq.com">LionCredo</a> */ @WebServlet(name="firstServlet",urlPatterns="/firstServlet") public class ServletTest1 extends HttpServlet{ private static final long serialVersionUID = -2149324298582445679L; @Override public void init(ServletConfig config) throws ServletException { //初始化Servlet的時候,能夠在這裏完成某些初始化的方法. super.init(config); } @Override protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { //大部分時候,對於全部請求都是同樣的話,能夠重寫HttpServlet的Service方法來替代doGet/doPost這些方法. super.service(arg0, arg1); } @Override public void destroy() { // 在銷燬Servlet以前,須要完成某些資源的回收,好比關閉數據庫連接等,能夠寫在這裏. super.destroy(); } }
public abstract class javax.servlet.http
•doGet,若是 servlet 支持 HTTP GET 請求
•doPost,用於 HTTP POST 請求
•doPut,用於 HTTP PUT 請求
•doDelete,用於 HTTP DELETE 請求
•init 和 destroy,用於管理 servlet 的生命週期內保存的資源
•getServletInfo,servlet 使用它提供有關其自身的信息
幾乎沒有理由重寫 service 方法。service 經過將標準 HTTP 請求分發給每一個 HTTP 請求類型的處理程序方法(上面列出的 doXXX 方法)來處理它們。
一樣,幾乎沒有理由重寫 doOptions 和 doTrace 方法。
servlet 一般運行在多線程服務器上,所以應該意識到 servlet 必須處理併發請求並當心地同步對共享資源的訪問。共享資源包括內存數據(好比實例或類變量)和外部對象(好比文件、數據庫鏈接和網絡鏈接)。有關在 Java 程序中處理多個線程的更多信息,請參見 Java Tutorial on Multithreaded Programming。
上面是查閱官方的API所得的說明,實際上javaweb開發中,不多有web開發徹底嚴格的使用Http協議.因此說大好青年浪費不是沒道理的,但商業的實現手段就是商業的實現手段,技術永遠是其次的.固然,REST這個嘛,第二春....再詳細的方法就看HttpServlet的源碼或者API.
另外,爲何不重寫servlet的service方法有更詳細的文章:http://my.oschina.net/dtkking/blog/89443
===========================================
Implements: Servlet, ServletConfig, java.io.Serializable
Extended by: HttpServlet
定義通常的、與協議無關的 servlet。要編寫用於 Web 上的 HTTP servlet,請改成擴展 javax.servlet.http.HttpServlet。
GenericServlet 實現 Servlet 和 ServletConfig 接口。servlet 能夠直接擴展 GenericServlet,儘管擴展特定於協議的子類(好比 HttpServlet)更爲常見。
GenericServlet 使編寫 servlet 變得更容易。它提供生命週期方法 init 和 destroy 的簡單版本,以及 ServletConfig 接口中的方法的簡單版本。GenericServlet 還實現 log 方法,在 ServletContext 接口中對此進行了聲明。
要編寫通常的 servlet,只需重寫抽象 service 方法便可。
剝離了一大堆註釋的源碼:
package javax.servlet; import java.io.IOException; import java.util.Enumeration; public abstract class GenericServlet implements Servlet, ServletConfig, java.io.Serializable { private static final long serialVersionUID = 1L; //java語言的關鍵字,變量修飾符,若是用transient聲明一個實例變量,當對象存儲時,它的值不須要維持。 //Java的serialization提供了一種持久化對象實例的機制。 //當持久化對象時,可能有一個特殊的對象數據成員,咱們不想用serialization機制來保存它。 //爲了在一個特定對象的一個域上關閉serialization,能夠在這個域前加上關鍵字transient。 //當一個對象被串行化的時候,transient型變量的值不包括在串行化的表示中,然而非transient型的變量是被包括進去的。 private transient ServletConfig config; public GenericServlet() { //構造方法 } @Override public void destroy() { //銷燬 } @Override public String getInitParameter(String name) { return getServletConfig().getInitParameter(name); } @Override public Enumeration<String> getInitParameterNames() { return getServletConfig().getInitParameterNames(); } @Override public ServletConfig getServletConfig() { return config; } */ @Override public ServletContext getServletContext() { return getServletConfig().getServletContext(); } @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 } 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(); } }
能夠看到,HttpServlet,是基於Http協議擴展了GenericServlet的抽象類.
而 GenericServlet是實現了Servlet,ServletConfig,以及必須的Serializable序列化.下面主要看實現的2個接口,Servlet,ServletConfig都定義了那些接口.===========================================================
能夠看源碼,API,均可以發現servlet是一個接口.定義了五個方法.
package javax.servlet; import java.io.IOException; public interface Servlet { public void init(ServletConfig config) throws ServletException; public ServletConfig getServletConfig(); public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException; public String getServletInfo(); public void destroy(); }
看上圖Servlet接口中有 getServletConfig.從這個接口的定義能夠結合起來.
package javax.servlet; import java.util.Enumeration; public interface ServletConfig { public String getServletName(); public ServletContext getServletContext(); public String getInitParameter(String name); public Enumeration<String> getInitParameterNames(); }
==========================================================================
具體的接口定義和抽象類的實現,能夠看看源代碼,不過話說回來,我如今的目的也就是搞清楚,而非是本身寫,那樣精力消耗太大.畢竟源碼是輕易得到的,想看明白就好了.
=====================================================================================================
下一個將粗略說下HttpServletRequest , HttpServletResponse .這兩個寫下就知道是什麼狀況了.
HttpServletRequest , HttpServletResponse,在Servlet裏是什麼意思,一目瞭然.
Web基於HTTP的開發中,這兩貨是每天用的東西.二者都是接口.
客戶端對於Servlet的每次訪問請求,Servlet容器(如Tomcat)都會建立一個封裝HTTP請求的對象和一個表明HTTP響應的對象,當調用Servlet的doGet或doPost方法時,這兩個對象會做爲參數被傳遞進去
HttpServletRequest對象表明客戶端的請求,當客戶端經過HTTP協議訪問服務器時,所發出的HTTP請求消息被封裝在此對象之中,經過這個對象提供的方法,便可得到客戶端發出的請求信息。
具體的示例嘛...:日,不想寫了,這些太簡單了,隨便去網上找的DEMO看啦.
讀取請求參數的方法
經過HttpServletRequest對象的如下方法讀取GET/POST方式下傳遞的參數
getParameter
getParameterValues
輸出響應正文(實體內容)輸出響應正文的方法
public class Servlet1 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response){ response.setContentType("text/html"); PrintWriter out = response.getWriter(); String userName = request.getParameter("userName"); //經過PrintWriter類型對象out的println方法,輸出內容至瀏覽器 out.println("username:"+userName+"<br/>"); //顯式清理緩存和關閉 out.flush(); out.close(); }如上示例.
HttpServletResponse其它經常使用方法