提前聲明:個人說的不一定對,如有錯誤之處,請批評指出.
JSP的本質就是Servlet,或者說(是吧,開始說的是java,汗)JavaWeb開發的本質也就是Servlet+JDBC.任何性質的框架技術最底層的依然是基於他們2個.因此如果自己想寫一套如SSH那樣的框架技術,Java最底層的東西是必須掌握的.
Servlet被稱爲"服務器端小程序."是運行在服務器端的程序,用於處理以及響應客戶端的請求.
HTTP 目前支持 7 種請求方法: GET 、 POST 、 PUT 、 DELETE 和 TARCE,HEAD 、 OPTIONS .前四個都是客戶端請求數據這類相關的方法.
- GET 請求獲取由Request-URI所標識的資源。
- POST 在Request-URI所標識的資源後附加新的數據。
- PUT 請求服務器存儲一個資源,並用Request-URI作爲其標識。
- DELETE 請求服務器刪除由Request-URI所標識的資源。
- TRACE 請求服務器回送收到的請求信息,主要用語測試或診斷。
- HEAD 請求獲取由Request-URI所標識的資源的響應消息報頭。
- OPTIONS 請求查詢服務器的性能,或查詢與資源相關的選項和需求。
我在這裏只是列出HTTP的請求方法,具體的HTTP協議請參考這篇文章:http://my.oschina.net/zhaoqian/blog/90315
Servlet是個特殊的類,這個類必須繼承HttpServlet.Servlet提供了相對於HTTP數據請求的四個方法的請求(其他三個也提供了,但我懶得寫了,很少用到).
- doGet:用於響應上面綠色字體的GET請求.
- doPost:用於響應客戶端的POST請求.
- doPut:用於響應客戶端的PUT請求.
- doDelete:用於響應客戶端的Delete請求.
事實上,HTTP這個大好青年被浪費了,大部分我們就是使用GET/POST請求,至於PUT/DELETE都不知道被遺棄到哪裏去了.但最近幾年興起的一種REST模型的WEB服務,讓HTTP協議發出了第二春.具體詳見:http://my.oschina.net/zhaoqian/blog/90321
而諸如Struts2,SpringMVC這類的框架,也就是使用GET/POST,但工作時間久後,越發的感覺到,很多新技術,沒必要去追,所需要的是,搞清楚追底層的,以不變的底層去應對萬變的新技術.
Servlet的示例代碼:
01 |
package org.credo.test; |
03 |
import java.io.IOException; |
05 |
import javax.servlet.ServletConfig; |
06 |
import javax.servlet.ServletException; |
07 |
import javax.servlet.annotation.WebServlet; |
08 |
import javax.servlet.http.HttpServlet; |
09 |
import javax.servlet.http.HttpServletRequest; |
10 |
import javax.servlet.http.HttpServletResponse; |
13 |
*
<P>Project: Credo's Base</P> |
14 |
*
<P>Description:Servlet3.0的第一個測試. </P> |
15 |
*
<P>Copyright (c) 2012 LionCredo.All Rights Reserved.</P> |
18 |
@WebServlet (name= "firstServlet" ,urlPatterns= "/firstServlet" ) |
19 |
public class ServletTest1 extends HttpServlet{ |
21 |
private static final long serialVersionUID
= -2149324298582445679L; |
24 |
public void init(ServletConfig
config) throws ServletException
{ |
30 |
protected void service(HttpServletRequest
arg0, HttpServletResponse arg1) throws ServletException,
IOException { |
32 |
super .service(arg0,
arg1); |
36 |
public void destroy()
{ |
HttpServlet
public
abstract class javax.servlet.http
Extends: GenericServlet
Implements: java.io.Serializable
提供將要被子類化以創建適用於 Web 站點的 HTTP servlet 的抽象類。HttpServlet 的子類至少必須重寫一個方法,該方法通常是以下這些方法之一:
•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所得的說明,大概可以看看,雖說不官方推薦重寫Service方法,但實際上javaweb開發中,很少有web開發完全嚴格的使用Http協議.所以說大好青年浪費不是沒道理的,但商業的實現手段就是商業的實現手段,技術永遠是其次的.當然,REST這個嘛,第二春....再詳細的方法就看HttpServlet的源碼或者API.
===========================================
一個Servlet繼承抽象類HttpServlet,而HttpServlet繼承GenericServlet,
abstract GenericServlet
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 方法即可。
剝離了一大堆註釋的源碼:
01 |
package javax.servlet; |
03 |
import java.io.IOException; |
04 |
import java.util.Enumeration; |
06 |
public abstract class GenericServlet implements Servlet,
ServletConfig, |
07 |
java.io.Serializable
{ |
09 |
private static final long serialVersionUID
= 1L; |
16 |
private transient ServletConfig
config; |
18 |
public GenericServlet()
{ |
23 |
public void destroy()
{ |
28 |
public String
getInitParameter(String name) { |
29 |
return getServletConfig().getInitParameter(name); |
33 |
public Enumeration<String>
getInitParameterNames() { |
34 |
return getServletConfig().getInitParameterNames(); |
38 |
public ServletConfig
getServletConfig() { |
44 |
public ServletContext
getServletContext() { |
45 |
return getServletConfig().getServletContext(); |
49 |
public String
getServletInfo() { |
54 |
public void init(ServletConfig
config) throws ServletException
{ |
59 |
public void init() throws ServletException
{ |
63 |
public void log(String
msg) { |
64 |
getServletContext().log(getServletName()
+ ":
" +
msg); |
67 |
public void log(String
message, Throwable t) { |
68 |
getServletContext().log(getServletName()
+ ":
" +
message, t); |
72 |
public abstract void service(ServletRequest
req, ServletResponse res) |
73 |
throws ServletException,
IOException; |
76 |
public String
getServletName() { |
77 |
return config.getServletName(); |
可以看到,HttpServlet,是基於Http協議擴展了GenericServlet的抽象類.
而 GenericServlet是實現了Servlet,ServletConfig,以及必須的Serializable序列化.下面主要看實現的2個接口,Servlet,ServletConfig都定義了那些接口.
===========================================================
public interface javax.servlet
Implemented by: FacesServlet, GenericServlet, JspPage
定義所有 servlet 都必須實現的方法。
servlet 是運行在 Web 服務器中的小型 Java 程序。servlet 通常通過 HTTP(超文本傳輸協議)接收和響應來自 Web 客戶端的請求。
要實現此接口,可以編寫一個擴展 javax.servlet.GenericServlet 的一般 servlet,或者編寫一個擴展 javax.servlet.http.HttpServlet
的 HTTP servlet。
此接口定義了初始化 servlet 的方法、爲請求提供服務的方法和從服務器移除 servlet 的方法。這些方法稱爲生命週期方法,它們是按以下順序調用的:
1.構造 servlet,然後使用 init 方法將其初始化。
2.處理來自客戶端的對 service 方法的所有調用。
3.從服務中取出 servlet,然後使用 destroy 方法銷燬它,最後進行垃圾回收並終止它。
除了生命週期方法之外,此接口還提供了
getServletConfig 方法和 getServletInfo 方法,servlet 可使用前一種方法獲得任何啓動信息,而後一種方法允許 servlet 返回有關其自身的基本信息,比如作者、版本和版權。
可以看源碼,API,都可以發現servlet是一個接口.定義了五個方法.
01 |
package javax.servlet; |
03 |
import java.io.IOException; |
05 |
public interface Servlet
{ |
07 |
public void init(ServletConfig
config) throws ServletException; |
09 |
public ServletConfig
getServletConfig(); |
11 |
public void service(ServletRequest
req, ServletResponse res) |
12 |
throws ServletException,
IOException; |
14 |
public String
getServletInfo(); |
16 |
public void destroy(); |
public interface javax.servlet ServletConfig
Implemented by: GenericServlet
servlet 容器使用的 servlet 配置對象,該對象在初始化期間將信息傳遞給 servlet。
看上圖Servlet接口中有 getServletConfig.從這個接口的定義可以結合起來.
01 |
package javax.servlet; |
03 |
import java.util.Enumeration; |
05 |
public interface ServletConfig
{ |
07 |
public String
getServletName(); |
09 |
public ServletContext
getServletContext(); |
11 |
public String
getInitParameter(String name); |
13 |
public Enumeration<String>
getInitParameterNames(); |
==========================================================================
可以看到,正常下我們使用的的 Servlet extend httpServlet,
然後實質上的httpServlet extends
GenericServlet ,
而GenericServlet實現implements
1.接口Servlet,
2.接口ServletConfig,以及 3.java.io.Serializable.
具體的接口定義和抽象類的實現,可以看看源代碼,不過話說回來,我現在的目的也就是搞清楚,而非是自己寫,那樣精力消耗太大.畢竟源碼是輕易獲得的,想看明白就行了.
=====================================================================================================
HttpServletRequest , HttpServletResponse
下一個將粗略說下HttpServletRequest , HttpServletResponse .這兩個寫下就知道是什麼情況了.
HttpServletRequest , HttpServletResponse,在Servlet裏是什麼意思,一目瞭然.
Web基於HTTP的開發中,這兩貨是天天用的東西.兩者都是接口.
HttpServletRequest, HttpServletResponse對象簡介:
客戶端對於Servlet的每次訪問請求,Servlet容器(如Tomcat)都會創建一個封裝HTTP請求的對象和一個代表HTTP響應的對象,當調用Servlet的doGet或doPost方法時,這兩個對象會作爲參數被傳遞進去
HttpServletRequest對象代表客戶端的請求,當客戶端通過HTTP協議訪問服務器時,所發出的HTTP請求消息被封裝在此對象之中,通過這個對象提供的方法,即可獲得客戶端發出的請求信息。
HttpServletRequest對象最基本的應用是獲取瀏覽器傳遞給Web服務器的請求參數信息
請求參數:
▪GET方式下,URL地址後的附加信息
▪POST方式下,HTTP請求消息中的實體內容部分
具體的示例嘛...:日,不想寫了,這些太簡單了,隨便去網上找的DEMO看啦.
讀取請求參數的方法
通過HttpServletRequest對象的以下方法讀取GET/POST方式下傳遞的參數
getParameter
getParameterValues
HttpServletResponse對象代表服務器端對客戶端的響應,用於封裝HTTP響應消息
輸出響應正文(實體內容)輸出響應正文的方法
▪getWriter
返回一個(文本)字符輸出流對象
專用於輸出內容爲文本字符的網頁文檔
▪getOutPutStream
返回一個字節輸出流對象
如果要輸出二進制格式的響應正文,應該使用該方法
01 |
public class Servlet1 extends HttpServlet
{ |
02 |
public void doGet(HttpServletRequest
request, HttpServletResponse response){ |
03 |
response.setContentType( "text/html" ); |
04 |
PrintWriter
out = response.getWriter(); |
05 |
String
userName = request.getParameter( "userName" ); |
07 |
out.println( "username:" +userName+ "<br/>" ); |
如上示例.
HttpServletResponse其它常用方法
}字符集編碼問題
}重定向