MVC 架構-servlet

  1. M:model 模型 負責各個功能,javaBean
  2. V:View 視圖,顯示和用戶交互 
  3. C:controller 控制器  負責分發:將視圖和模型對應起來,接受請求,並將改請求跳轉模型,模型進行處理,然後將處理結果在經過控制器返回給視圖。

controller 一般都是使用Servelet實現控制器,

Servelet:是一個Java 類,處理請求和發送響應的一個過程,爲了實現動態頁面(開發一個Java程序向瀏覽器輸出數據)而衍生出來的,符合一定的規範,也就是說如果一個類符合一定規範,那麼這個類就是一個Servelet這個類就是

  1. 必須繼承javax.servelet.http.HttpServelet
  2. 重寫其中的doGet() 或者 doPost() 方法
    1. doGet() 接受並處理所有get提交方式的請求
    2. doPost() 接受並處理所有post提交方式的請求
public class WelcomeServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
        System.out.println("do get 2");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
        System.out.println("do post 2");

    }
}

理解這個得前提是理解一些http協議,和B/S 模式(瀏覽器/服務器),瀏覽器/服務器,瀏覽器通過網址來訪問服務器

Tomacat和servlet的關係:

Tomcat是Web應用服務器,是一個Servlet/JSP 容器,Tomcat作爲Servlet容器,負責處理客戶請求,把請求傳送給Servelt,並將servlet的響應傳送會客戶,而servlet是一種運行在支持Java語言的服務器上的組件,Servlet至於常見的應用是擴展Java web 服務器功能。

瀏覽器發送的是一個請求文本,接受到的也是一個響應文本,

以上的步驟是:

  1. Tomcat將http請求文本接受並解析,然後封裝爲HttpServeltRequest類型的request對象,所以有的HTTP頭數據可以通過request對象調用對應的方法查看到。
  2. Tomcat 同時要響應的信息封裝爲HttpServletResponse類型的request對象,通過設置response 屬性就是控制輸出到瀏覽器的內容,然後將response 交給Tomcat,tomcat就會將其變爲響應文本的格式發送給瀏覽器

Java Servlet API 就是Servlet容器(tomcat)和servlet之間的接口,它定義了servlet各種方法,還定義了servlet容器傳送給servlet的對象類,其中最重要的就是ServletRequest和ServletResponse,所以我們在編寫servlet 的時候,需要實現servlet接口,按照其規範來操作。

Servelet的使用

Servelet2.5: 必須配置web.xml

Servelet3.0 :@WebServlet

第一種配置文件的方式:

web.xml 內容:

View 種的標籤:

<a href="WelcomeServlet">
  WelcomeServlet
</a>

上面當點擊view 中的

後面會發送的事情如下:

  1. Web 項目會在web.xml中  根據 servlet-mapping 種的 url-pattern 標籤進行路徑的匹配,匹配之後
  2. 尋找在 1 中尋找在 servlet 中的的  servlet-name 和servlet-mapping 中的  servlet-name 具有相同的名字。
  3. 然後servlet 中 servlet-class 指定的類就是點擊鏈接後找到的對應的servelet

以上的執行過程:

  1. 編寫一個類,集成HttpServlet
  2. 重寫doGet 和 doPost
  3. web.xml 中的映射關係

 

項目中的web和src 都是項目的根目錄,當index發出一個請求的時候,首先會在web目錄下找對應的響應,然後再去src目錄下掃描對應的響應。

如果講url改爲,<a href="a/WelcomeServlet2"> 在web目錄或者src目錄找a目錄,然後再a目錄中找對應的響應

jsp中的/ 代表服務器的根路徑

web.xml 中的/ 代表項目的根路徑

servlet生命週期: 加載(servlet 容器自動處理) -> 初始化-> 服務(重點) -> 銷燬 -> 卸載(servlet 容器自動處理)

服務: 抽象service()方法  (doGet  doPost)

初始化: init()方法,該方法在servlet 被加載並實例化以後執行

銷燬:  destroy servlet 被系統回收的時候會執行

第一次訪問servlet的時候,init 和 service 都會觸發(可以設置爲服務器啓動的時候觸發

@WebServlet(value = "/WelcomeServlet", loadOnStartup = 1)

),當第二次觸發的時候就只會觸發service,調用幾次就會觸發 幾次 service,當在關閉服務器的時候就會去調用 destroy 方法, 

Servlet API, 由兩個軟件包組成,對應於HTTP協議的軟件包,以及非HTTP協議意外的其他軟件包,我們學習的servlet,是爲javax.servlet.http 包中的類和接口,是基礎的http協議。

servlet 的繼承關係

 

HttpServlet在實現Servlet接口時,覆寫了service方法,該方法體內的代碼會自動判斷用戶的請求方式,如爲GET請求,則調用HttpServlet的doGet方法,如爲Post請求,則調用doPost方法。因此,開發人員在編寫Servlet時,通常只需要覆寫doGet或doPost方法,而不要去覆寫service方法。

HttpServlet繼承了GenaricServlet方法,這是一個通用的Servlet接口實現的抽象通用類,而Servlet接口有以下幾個方法

    void init(ServletConfig var1) throws ServletException;

    ServletConfig getServletConfig();

    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    String getServletInfo();

    void destroy();

這裏可以看見servlet生命週期的三個關鍵方法,init、service、destroy還有就是 getServletConfig()方法來獲取ServletConfig對象,ServletConfig對象可以獲取到Servlet的一些信息,ServletName、ServletContext、InitParameter、InitParameterNames、通過查看ServletConfig這個接口就可以知道

public interface ServletConfig {
    String getServletName();

    ServletContext getServletContext();

    String getInitParameter(String var1);

    Enumeration<String> getInitParameterNames();

此外GenericServlet除了實現Servlet接口外,還實現了ServletConfig接口,那樣,就可以直接獲取ServletContext了。

GenericServlet中實現了Servlet 中的實現了Servlet 中的方法,但是可以發現有的方法實現了2遍,有空實現

    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }

    public void init() throws ServletException {
    }

這樣的實現是有一定的好處的,在正常初始化的時候(並不需要重寫用戶的init方法及加上用戶的邏輯)當繼承了GenericServlet的時候就會調用帶有參數的init方法,並將config賦值,上面可以看見還有一個getServletConfig的方法,在其他地方也就可以獲取得到這個congfig並使用,但是當用戶需要重寫nit方法及加上用戶的邏輯的時候,如果沒有這個init() 方法,那麼在GenericServlet 中就不會再去執行init(config) 方法了(被重寫了),所以在其他地方執行getServletConfig獲取到的就是null 了,而由這個init() 方法就可以避免這個問題了,因爲用戶重寫的init()方法是而不是init(config),所以在GenericServlet中init(cofig) 方法還是可以初始化config 的。

    public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

這個方法並沒有被實現,且參數還是ServletRequest,ServletResponse。並沒有跟http相關對象掛鉤,所以我們接着往下面看。

繼續看HttpServlet 實現類:繼承了GenericServlet類,通過我們上面的推測,這個類主要的功能肯定是實現service方法的各種細節和設計。並且通過類名可以知道,該類就跟http掛鉤了。

該方法中就做一件事情,就是將ServletRequest和ServletResponse這兩個對象強轉爲HttpServletRequest和HttpServletResponse對象。爲什麼能這樣轉?首先要知道req、res是什麼類型,通過打印System.out.println(req),可以知道,req實際上的類型是org.apache.catalina.connector.RequestFacade

httpServletRequest和HttpServletResponse對象之後,在調用

service(HttpServletRequest req, HttpServletResponse resp)方法, 而這個方法就是會判斷請求來的具體是哪個方法,沒每種的處理方法也是不一樣的,我們常用的就是get,post,所以這裏就回到了我們上面編寫servlet時的情況,繼承httpServlet,而只要重寫兩個方法,一個doGet,一個doPost,其實就是service方法會調用這兩個方法中的一個(看請求方式)。

3.0 的方式給當前servlet設置初始值,但是隻是屬於當前的某一個servlet,無法爲整個web容器設置初始化參數,任然需要在web.xml  中配置。

<context-param>
    <param-name>param-name</param-name>
    <param-value>param-value</param-value>
</context-param>

httpServletRequest 中的方法通request 中的方法是一致的, 如, setAttribute(), getCookies(), getMethod()

相同的 httpServletResponse 也是的。

幾個重點的對象。ServletConfig、ServletContext,request、response

ServletConfig :

getServletName();  //獲取servlet的名稱,也就是我們在web.xml中配置的servlet-name

getServletContext(); //獲取ServletContext對象,該對象的作用看下面講解

getInitParameter(String); //獲取在servlet中初始化參數的值。這裏注意與全局初始化參數的區分。這個獲取的只是在該servlet下的初始化參數,web.xml 中的配置:

 

使用:

ServletContext 

獲取途徑:getServletContext(); 、getServletConfig().getServletContext();

tomcat爲每個web項目都創建一個ServletContext實例,tomcat在啓動時創建,服務器關閉時銷燬,在一個web項目中共享數據,管理web項目資源,爲整個web配置公共信息等,通俗點講,就是一個web項目,就存在一個ServletContext實例,每個Servlet讀可以訪問到它。

web項目中共享數據,

setAttribute(String name, Object obj) 在web項目範圍內存放內容,以便讓在web項目中所有的servlet讀能訪問到

getAttribute(String name) 通過指定名稱獲得內容

removeAttribute(String name) 通過指定名稱移除內容 

整個web項目初始化參數 //這個就是全局初始化參數,每個Servlet中都能獲取到該初始化值

getInitPatameter(String name) //通過指定名稱獲取初始化值

getInitParameterNames() //獲得枚舉類型

web.xml 配置 整個web項目的初始化,需要通過web.xml 配置

request 對象

request就是將請求文本封裝而成的對象,所以通過request能獲得請求文本中的所有內容,請求頭、請求體、請求行 。

String getHeader(java.lang.String name) 獲得指定頭內容String【】

long getDateHeader(java.lang.String name) 獲得指定頭內容Date

int getIntHeader(java.lang.String name)  獲得指定頭內容int

Enumeration getHeaders(java.lang.String name) 獲得指定名稱所有內容

 

3請求體的獲取 -- 請求參數的獲取

分兩種,一種get請求,一種post請求

get請求參數:http://localhost:8080/test01/MyServlet?username=jack&password=1234

post請求參數: <form method="post"><input type="text" name="username">

String request.getParameter(String) 獲得指定名稱,一個請求參數值。

String[] request.getParameterValues(String) 獲得指定名稱,所有請求參數值。例如:checkbox、select等

Map<String , String[]> request.getParameterMap() 獲得所有的請求參數

 

4請求轉發

request.getRequestDispatcher(String path).forward(request,response); //path:轉發後跳轉的頁面,這裏不管用不用"/"開頭,都是以web項目根開始,因爲這是請求轉發,請求轉發只侷限與在同一個web項目下使用,所以這裏一直都是從web項目根下開始的,

web項目根:

開發:G:\Workspaces\test01\WebRoot\..

運行時:D:\java\tomcat\apache-tomcat-7.0.53\webapps\test01\..

 web站點根:

運行時:D:\java\tomcat\apache-tomcat-7.0.53\webapps\..

從這裏可以看出,web項目根就是從該web項目名開始,所以我們請求轉發時,只需要接着項目名後面需要訪問的路徑寫就行了,

特點:瀏覽器中url不會改變,也就是瀏覽器不知道服務器做了什麼,是服務器幫我們跳轉頁面的,並且在轉發後的頁面,能夠繼續使用原先的request,因爲是原先的request,所以request域中的屬性都可以繼續獲取到。

response對象

常用的一個方法:response.setHeader(java.lang.String name, java.lang.String value) 設置指定的頭,一般常用。

部分內容來源於這個博客,建議跳轉去看整篇博客

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章