1. 程式人生 > >Servlet的總結與解釋(定義,生命週期,JSP,執行緒安全)

Servlet的總結與解釋(定義,生命週期,JSP,執行緒安全)

servlet是web三大元件之一.是最重要元件

  1. servlet是什麼? 可以幹什麼?
  2. Servlet介面與HttpServlet
  3. servlet的生命週期
  4. servlet的常見配置
  5. Servlet如何接收資料,響應資料?
  6. JSP是什麼? 為什麼要有JSP?
  7. servlet是執行緒安全的嗎? 不是的話,解決方案是什麼?

 

1.servlet是什麼? 可以幹什麼?

Servlet是web應用中的java程式,它可以對使用者的請求進行處理,並做出響應.

 

2.當然Servlet從狹義上講它是一個介面,裡面規定了一些api.廣義上講指實現servlet介面的類.我們一般說的都是廣義上的.

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介面,要實現的方法太多,而且有些內容重複.tomcat就幫我們寫好了一個很好的實現類 HttpServlet,我們只要繼承它就可以.

public class TestServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

    public TestServlet() {
        super();      
    }

public void init(ServletConfig config) throws ServletException {
//伺服器啟動後,客戶端第一次訪問時執行
}

public void destroy() {
//伺服器關閉時執行
}

protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//每訪問一次,就會呼叫一次
//屬於web層業務邏輯
}
}

上面的程式碼,簡單提及到servlet的生命週期,下一節仔細講一下.

當然如果,我們不需要初始化等與業務邏輯無關的方法,那麼只覆蓋父類的 doGet()  doPost() 就可以.也就是eclipse中預設建立servlet中的方法

public class HelloServlet extends HttpServlet {

private static final long serialVersionUID = 1L;
    public HelloServlet() {
        super();
    }
protected void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.getWriter().append("Served at: ").append(request.getContextPath());

}

protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}

 

 

3.servlet的生命週期

Servlet的生命週期,看下圖

  1. 當有客戶向伺服器發出請求後,伺服器通過對映檔案(web.xml或註解),找到servlet.對它進行編譯並執行init(),就是初始化操作.
  2. 伺服器建立servlet是以單例模式建立的.所以上圖中,thread A和thread B會訪問同一個servlet.這樣在減少資源使用的情況下,同時可能造成執行緒安全問題.(這個問題會在文章後面細說)
  3. 伺服器會幫我們建立 http的request和response.幫助我們獲取客戶端資訊,更方便的響應客戶請求
  4. 有了servlet物件,request和response之後,就可以執行service()了.service()中有會呼叫service層中的方法,以完成整個邏輯.
  5. 最後,在伺服器關閉時.JVM幫我們回收servlet物件.

 

下面這個圖,是我訪問百度,通過chrome瀏覽器可以看到的一部分http請求與響應.當然這些資訊都是可以通過,service()中request得到的

 

4.servlet的常見配置

Eclipse中 2.5 版本之前,都是使用web.xml來配置的.之後採用註解方式配置.當然兩者各有利弊.在xml中配置,對於需要時不時修改一下的配置是合適的.而註解方式更適合,配置完成後基本不做修改的配置.這裡不細講了.感興趣可以自行百度w3School

 

5.Servlet如何接收資料,響應資料?

在tomcat中,會把使用者的http請求內容,處理成一個request物件.同時建立一個response物件用於響應使用者.

至於具體是如何建立的request的物件.我並沒有看過具體的原始碼.在這裡僅僅做一個簡單的推測.在tomcat接收到http請求,這個請求會把請求行,請求頭,請求體裡的內容一段一段的解析.做一些複雜的字串處理.然後再將各種資訊整合分類.

Ajax:往往用於非同步傳輸資料,請求沒有變化,響應時,不需要請求轉發或者重定向.一般是把資料轉換為JSON字串,然後傳給客戶端.記得伺服器響應時,要設定好response.setContentType("application/json;charset=utf-8")

 

6.JSP是什麼? 為什麼要有JSP?

JSP是一種特殊的servlet.每個JSP都對應一個java物件.具體的程式碼可以開啟tomcat.以我的為例,該目錄下可以看到具體的程式碼

C:\Tomcat 8.0\webapps\work\Catalina\localhost\mycrm\org\apache\jsp

 

我們可以看到每個jsp都對應著一個.class和.java檔案.開啟.java檔案之後

public final class top_jsp extends org.apache.jasper.runtime.HttpJspBase

    implements org.apache.jasper.runtime.JspSourceDependent {}

裡面有類似與servlet的init,destroy,service方法.在service()中,可以看到

 

從這裡可以引出,為什麼要有JSP?

在沒有JSP 之前,人們只能想上圖那樣,一行一行的將html的程式碼輸出.這是一件很枯燥且喪心病狂的一件事.導致了很多人接受不了.沒辦法,sun就推出了jsp.

以前說在JSP中內嵌java程式碼,後來才知道,是在java中嵌入html程式碼.當然了,JSP的表達方式和html非常相似.而且還可以動態生成程式碼.方便多了.而且之後也推出了想JSTL,EL,更加使JSP中的Java程式碼變得少了.

另外:JSP有9個內建物件.為什麼能有呢?因為它在service()中建立了9個物件.就當然可以在JSP頁面中使用了.

 

7.servlet是執行緒安全的嗎? 不是的話,解決方案是什麼?

在 Web 應用程式中,一個 Servlet 在一個時刻可能被多個使用者同時訪問。這時 Web 容器將為每個使用者建立一個執行緒來執行 Servlet。如果 Servlet 不涉及共享資源的問題,不必關心多執行緒問題。但如果 Servlet 需要共享資源,需要保證 Servlet 是執行緒安全的。

也就是說:servlet在有共享資源下,很可能出現執行緒安全問題!

我知道的解決方法有3種

  1. 不使用可變的共享變數.可以使用final修飾的變數.但是一般的成員變數,就不能使用了.這從根本上解決了問題.但是呢,沒有了共享變數,在方法中可能要多次建立相同的物件.造成資源的浪費.
  2. 使用synchronized 來對共享變數的操作進行加鎖.這樣會大大降低併發性.
  3. 繼承單執行緒介面,這個根本不可能使用.單執行緒的話,就可以當單機遊戲玩了.

 

當然,現在的框架都解決了servlet的執行緒安全問題.那個就更復雜了.一言半語講不清的.

才疏學淺,若有不當之處,請指出,共同學習!

 

參考資源

http://www.runoob.com/servlet/