Brian的雜記
  • Introduction
  • Brian's 雜記
    • My Awesome API
    • FB 大頭貼
    • 硬體雜記
    • PHP
    • project
      • 模擬器
      • WAMP
    • WinMerge
    • 雜記
      • LINQ
      • 方法
      • Grid View
      • namespace
      • global
      • 物件導向
      • Excel
      • VS2017
      • single sign on
      • Master
      • Https
      • 憑證
      • 略過憑證不符
      • NLog
      • 團隊開發
      • .NET Core
      • 共用網路上的芳鄰
      • 爬蟲
      • NPOI
      • RSS
      • 多執行緒
      • 記憶體回收
      • 密碼學
        • BCrypt
        • AES
      • 主機環境建置
      • Session
      • Error
      • IIS 相關
      • 無障礙相關
      • 介面
        • 影像地圖
      • telnet
        • smtp
      • nslookup
      • 協助客戶解決問題
      • 驗證欄位
      • 網站管理
      • 工具整理
    • 正規表示法
    • 影像處理
    • IntelliJ Idea
    • 觀念
      • Clean Code
        • 命名
        • 函式
        • 註解
        • 編排
        • 物件及資料結構
        • 錯誤處理
        • 邊界
        • 單元測試
        • 類別
      • Java 程式風格
      • Design Pattern
        • 單例模式
      • 同步
      • 畫圖
        • ER-Model
        • 類別圖
        • Use Case
        • 有限狀態機
      • 資料 API 文件 分析
      • CORS & SSL
      • 利用DISC幫助溝通
      • OAS
    • 檔案上傳
      • FileStore
      • App Engine
      • Google Storage
    • OAuth vs Open ID
    • MIME
    • 虛擬桌面
    • 待看資料
    • Selenium
    • CDN
    • HTTP
    • 編碼
    • 2nd-ML100Days
      • jupyter
    • 微服務
      • 設計
        • 1 ~ 5
        • 6
        • 7
        • 8
        • 9
    • Gradle
    • Maven
    • Error
    • 批次檔 BAT
    • Kurento
    • WebSocket & WebRTC
  • 需求面能力
    • User Story
  • Google Cloud Platform
    • Compute Engine
  • Python
    • 基本語法
    • Pandas
    • 套件
    • Matplotlib
    • Encoder
    • jupyter
  • Java
    • Java
      • File
      • Exception
      • 物件導向觀念
      • 加密
      • HTTP
      • 集合
      • Stream()
      • Web
      • ResultSet
      • JDK6
      • JDK8
    • 讀取、複寫MP3 Tag
    • Log4j2
    • Servlet
      • 容器
    • JSP
    • JBOSS
    • JWT
    • PreparedStatement
    • Error
    • Spring
      • Spring Boot
        • @Value
        • Build
      • RequestParameter
      • Error
      • Autowired
      • JPA
      • FeignClient
      • WebSocket
      • thymeleaf
      • Security
      • Test
      • Scheduled
      • Redirect
    • IntelliJ
  • Linux
    • Linux
    • Shell Script
    • Cygwin(在Windows執行Linux指令)
  • 前端
    • HTML
      • Link
    • CSS
      • Position
      • padding color
      • display
    • JS
      • jQuery
        • Select2
      • fancybox
      • ES6
      • 效能
      • GoogleMap API
        • Marker
        • InfoWindow
      • 事件
      • CKEditor
      • TGOS
      • JSON
      • QRcode
      • 核心概念
        • 物件 變數 型別
          • number
          • String
          • boolean
          • null & undefined
          • Symbol
        • JS 物件概念
        • 深入理解JS 函式物件
        • 更多ES2015/ES6 全新語言特性
      • Promise
    • 效果應用
  • 資料庫
    • 注意事項
    • MariaDB
    • MySQL
      • inner join 和 join
      • 字串比對
      • 倒數資料
    • SQL
      • DDL 資料定義語言
      • DML 資料操縱語言
      • DCL 資料控制語言
      • TCL 交易控制語言
      • T-SQL
      • CTE
      • JOIN
    • Oracle
    • MSSQL 操作
      • 新增使用者
      • SQL 指令
      • Sequence
    • 差異比較
    • MyBatis
    • Workbench 操作
    • SQL Injection
  • 版本控制
    • Gitlab
      • sign up
      • sign in
      • add project
      • add members
    • SourceGit
      • install
    • SmartGit
      • install
      • operate
      • git 操作雜記
    • TortoiseGit
    • Git
    • TFS
    • SVN
  • Test
    • 軟體測試原則
    • 演算法
    • XMind
      • install
    • Jenkins
      • 建置
    • HTTPie
    • Postman
    • 測試驅動開發
    • 撰寫測試的觀念
    • 測試框架
    • IoC & DI
    • 隔絕相依性的方式
    • JUnit
    • NUnit
    • 習慣
    • 虛設常式
  • Angular
    • hello world
    • ng-options
    • ES6
    • Build & Conponect
    • HttpClient
    • 部署
  • ASP.NET Web Form
    • Chapter 2
      • 2-1
        • 小東西
    • 略過請求驗證
  • Go
Powered by GitBook
On this page
  • 容器
  • JAVA程式
  • Servlet / JSP
  • 請求/回應的例子
  • 第一個Servlet
  • 第一個JSP
  • 關於 MVC/Model 2
  • URL模式
  • 只有 doGet()、doPost()?
  • 請求參數、標頭
  • getReader()、getInputStream()

Was this helpful?

  1. Java
  2. Servlet

容器

PreviousServletNextJSP

Last updated 4 years ago

Was this helpful?

容器

參考資料:()

JAVA程式

.java -編譯-> .class .class 為 JVM的執行檔

Servlet / JSP

容器的概念

類似List、Set這類的Collection,不過容器的概念更廣泛,在最基本的功能上,不只持有物件,還負責物件的生命週期&相關服務的連結。

說穿了,容器也是一個JAVA程式,運行在JVM上,但是它會幫你把 Servlet/JSP 中的JAVA物件(HttpServletRequest、HttpServletResponse等),轉換為HTTP那些文字性的通訊協定。

也可以想像成 Web容器 是一個伺服器,而我們寫的Servlet/JSP 就運行在上面。只要我們的 Servlet/JSP 符合 Web容器 的規範,就可以運行在各種不同的伺服器上。

如同

JVM     介於 Java程式    與 作業系統      之間
Web容器 介於 Servlet/JSP 與 實體Web伺服器 之間

也如同 撰寫Java 程式必須了解JVM/JRE 與我們的應用程式如何互動 撰寫Servlet/JSP 也必須知道容器如何與Servlet/JSP互動,如何管理Servlet (JSP最後也是轉譯、編譯、載入為Servlet,在容器的世界,真正負責請求、回應的是Servlet)

請求/回應的例子

1.客戶端(大部分是瀏覽器) 對Web 伺服器發出HTTP請求

2.Web 伺服器收到HTTP請求,將請求轉由Web 容器處理,Web 容器會剖析HTTP 請求內容,建立各種物件(HttpServletRequest、HttpServletResponse、HttpSession等)

3.Web 容器由請求的URL 來決定要使用哪個Servlet 來處理請求(事先由開發人員定義)

4.Servlet 根據請求物件(HttpServletRequest) 的資訊決定如何處理,透過回應物件(HttpServletResponse)來建立回應。

5.Web 容器與Web 伺服器溝通,Web 伺服器將回應轉換為HTTP 回應並傳回客戶端。

在Java EE 的領域無論是哪個技術,都與容器息息相關,寫Servlet/JSP 需要理解Web 容器,寫EJB 需要了解EJB 容器,寫應用程式客戶端 需要了解應用程式客戶端容器。

第一個Servlet

javax.servlet.http.HttpServletRequest 是 HTTP 請求的Java 物件,有關於HTTP 請求的資訊都是由它來取得。

javax.servlet.http.HttpServletResponse 則是HTTP回應的JAVA代表物件。

在Servlet 中從 response 取得PrintWriter,最後要不要呼叫close()呢? 一般是建議不需要主動呼叫close(),容器負責 HttpServletRequest、HttpServletResponse 物件的建立,也會處理最後的物件資源回收與銷毀,因此 close()可由容器處理(自行close() 在某些時候,像是過濾器(Filter) 的處理,可能會造成麻煩。

容器怎麼知道要由哪個Servlet 來處理請求? 在這個例子中,是透過標注 @WebServlet 來告知容器,這個Servlet 的名稱(name)是 HelloWorld,若沒有指定,預設採用類別的完整名稱。如果客戶端請求的URL是 /helloworld (urlPatterns),則是由這個 Servlet 來處理。

@WebServlet(name="HelloWorld", urlPatterns={"/helloworld"},
loadOnStartup=1)

http://localhost:8080/ServletDemo/helloworld

應用程式啟動後,並不會載入所有的Servlet。容器會在請求時,才將對應的Servlet類別載入、實例化、進行初始動作所必須花費的時間,才真正得到請求的處理。

如果希望啟動時,就將Servlet類別載入、實例化、並做好初始化,則可以使用 loadOnStartup 設定。設定大於0 的值(默認為-1),表示在啟動應用程式後就要初始化Servlet(而不是實例化)。數字表示 Servlet 的初始順序,容器必須保證有較小數字的 Servlet先初始化,如果有多個同個數字,則容器實作廠商可以自行決定要如何載入哪個Servlet。

像上方使用標注來定義Servlet 是Java EE 6 之後 Servlet 3.0 的功能。也可以使用 web.xml 來定義Servlet,就像在Java EE 5 中定義Servlet一樣。

<?xml version="1.0" encoding="UTF-8"?>  
<web-app version="4.0" 
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"   
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee  
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">  
    <servlet>
        <servlet-name>HelloWorld</servlet-name>
        <servlet-class>cc.openhome.HelloWorld</servlet-class>
         <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloWorld</servlet-name>
        <url-pattern>/helloworld</url-pattern>
    </servlet-mapping>
</web-app>

使用xml 來定義是比較麻煩,不過如果xml中<servlet-name> 和 標注的name相同,會把@WebServlet 的覆蓋掉。 可以使用標注當預設值,web.xml用來做日後更改設定值之用。

另外,有些Servlet 在定義時並不會使用 @WebServlet,像是使用框架時,會有擔任分派請求的Servlet,這類基本上會在web.xml中定義。

web.xml 也會用來定義一些應用程式的資源,像是初始參數、安全設定、JNDI(Java 命名與目錄介面)。

在上面的web.xml 中,若有客戶端請求 /helloworld,則是由 HelloWorld 這個Servlet來處理,這分別是由 <servlet-mapping> 中的 <url-pattern> 與 <servlet-name> 來定義,而 HelloWorld 名稱的Servlet,實際上是HelloWorld 類別的實例,這分別是由 <servlet> 中的 <servlet-name>與 <servlet-class>來定義。 如果有多個Servlet 在設定 <load-on-startup> 時使用了相同的數字,則依其在 web.xml 中設定的順序來初始 Servlet。

如果使用的是IDE,那基本上就可以執行應用程式並對 Servlet 發出請求了,實際上,IDE會將你的應用程式包裝為WAR (Web Archive),然後上傳至應用程式伺服器(Application Server) 完成部署(Deployment)。

所謂的War檔,實際上是一個副檔名為 .war的檔案,使用zip格式包裝壓縮,而當中的結構如下

/ServletDemo.war/
                /WEB-INF/
                        /classes/
                        |       /cc/
                        |          /openhome/
                        |                   |HelloWorld.class
                        |web.xml

也就是說,一個 Web 應用程式中,編譯出來的 .class 檔案,必須放置在 /WEB-INF/classes/ 資料夾中,並必須按照套件(Package)層次放在對應的資料夾內,如果你使用 web.xml 設定檔,則 web.xm l必須放置在 /WEB-INF/ 中。 WAR 檔案是 zip 壓縮格式,所謂的部署,就是將 WAR 檔上傳至應用程式伺服器,由伺服器解壓縮並讀取設定、載入 Servlet 後進行服務。

第一個JSP

關於 MVC/Model 2

URL模式

1. /XXXX/ /guest/

/guest/home.view /guest/test.view

2. .XXXX .view

所有.view 結尾的 3.

空字串是個特殊的URL,對應至環境根目錄,也就是 / 的請求 4. /

表示預設的Servlet。 5. 其餘的URL都是嚴格匹配(Exact match)

如果URL模式在設定比對的規則在某些URL有所重疊,會依照比對最嚴格的URL開始符合

只有 doGet()、doPost()?

解釋各種 Method ,還有RESTful。

請求參數、標頭

request.setCharacterEncoding("UTF-8");

從 Servlet 4.0 開始,也可以在 web.xml 中加入 ,設定整個應用程式要使用的請求參數編碼,如此一來,就不用特別在每次請求使用 HttpServletRequest 的 setCharacterEncoding() 方法來設定編碼了 例如:

<request-character-encoding>UTF-8</request-character-encoding>

當請求是用 GET 發送時,setCharacterEncoding() 沒有作用,究其原因,是因為處理 URI 的是 HTTP 伺服器,而非容器,對於 Tomcat 7 或先前版本附帶的 HTTP 伺服器來說,處理 URI 時使用的預設編碼是 ISO-8859-1,在不改變 Tomcat 附帶的 HTTP 伺服器 URI 編碼處理設定的情況下,常見使用底下的處理方式(若客戶端使用 UTF-8 發送請求):

String name = request.getParameter("name");
String name = new String(name.getBytes("ISO-8859-1"), "UTF-8");

從 Tomcat 8 之後,附帶的 HTTP 伺服器在 URI 編碼處理時預設使用 UTF-8 了,此時就不用如上自行轉換字串編碼了。

一旦開始學會從客戶端接受請求,取得請求參數或標頭等客戶端送出的資料之後,切記,永遠別相信你的客戶端是善良的,小心驗證、過濾請求參數或標頭等,以避免注入攻擊(Injection attack)之類的事情發生,永遠別把文件或書中簡單的範例程式直接拿來用,為了簡化範例,程式中往往不會考慮必要的驗證與過濾!

getReader()、getInputStream()

參考資料:()

參考資料:()

參考資料:()

參考資料:()

參考資料:()

https://openhome.cc/Gossip/ServletJSP/Container.html
https://openhome.cc/Gossip/ServletJSP/FirstJSP.html
https://openhome.cc/Gossip/ServletJSP/Model2.html
https://openhome.cc/Gossip/ServletJSP/DoGetDoPost.html
https://openhome.cc/Gossip/ServletJSP/RequestParameterHeader.html
https://openhome.cc/Gossip/ServletJSP/GetReaderInputStream.html