Servlet 基礎
當瀏覽器使用get方式提交資料的時候,servlet需要提供doGet()方法
哪些是get方式呢?
form預設的提交方式
如果通過一個超鏈訪問某個地址
如果在位址列直接輸入某個地址
ajax指定使用get方式的時候
--
當瀏覽器使用post方式提交資料的時候,servlet需要提供doPost()方法
哪些是post方式呢?
在form上顯示設定 method="post"的時候
ajax指定post方式的時候
--
service(HttpServletRequest , HttpServletResponse )
實際上,在執行doGet()或者doPost()之前,都會先執行service()
由service()方法進行判斷,到底該呼叫doGet()還是doPost()
可以發現,service(), doGet(), doPost() 三種方式的引數列表都是一樣的。
所以,有時候也會直接重寫service()方法,在其中提供相應的服務,就不用區分到底是get還是post了。
比如把前面的登入的LoginServlet,改為提供service方法,也可以達到相同的效果
--
為了成功獲取中文引數,需要做如下操作
1. login.html中加上
這句話的目的是告訴瀏覽器,等下發訊息給伺服器的時候,使用UTF-8編碼
2. login.html
form的method修改為post
3. 在servlet進行解碼和編碼
這樣就可以得到正確的中文引數了
這樣需要對每一個提交的資料都進行編碼和解碼處理,如果覺得麻煩,也可以使用一句話代替:
以上是使用UTF-8的方式獲取中文呢。 也可以使用GBK。把所有的UTF-8替換為GBK即可。 GB2312同理。
Tomcat預設的編碼格式是iso-8859-1,不能表示中文字元。這裡我們使用UTF-8字符集表示中文。
“page ”指示該頁面中程式碼的字元編碼是UTF-8。“head”指示瀏覽器使用UTF-8格式進行字元顯示。
Tomcat進行檔案和網路傳輸操作時,預設使用的編碼格式也是iso-8859-1,這裡我們指定傳輸時的編碼格式為“UTF-8”。
--
一個Servlet的生命週期由例項化,初始化,提供服務,銷燬,被回收幾個步驟組成例項化:
為LoginServlet顯式提供一個構造方法 LoginServlet()
然後通過瀏覽器訪問,就可以觀察到
"LoginServlet 構造方法 被呼叫"
無論訪問了多少次LoginServlet
LoginServlet構造方法只會執行一次,所以Servlet是單例項的
初始化:
init 方法是一個例項方法,所以會在構造方法執行後執行。
無論訪問了多少次LoginSerlvet
init初始化只會執行一次
提供服務:
接下來就是執行service()方法,然後通過瀏覽器傳遞過來的資訊進行判斷,是呼叫doGet()還是doPost()方法
在service()中就會編寫我們的業務程式碼,在本例中就是判斷使用者輸入的賬號和密碼是否正確
銷燬
在如下幾種情況下,會呼叫destroy()
1. 該Servlet所在的web應用重新啟動
在server.xml中配置該web應用的時候用到了
如果把 reloadable="false" 改為reloadable="true" 就表示有任何類發生的更新,web應用會自動重啟
當web應用自動重啟的時候,destroy()方法就會被呼叫
2. 關閉tomcat的時候 destroy()方法會被呼叫,但是這個一般都發生的很快,不易被發現。
在web.xml中,配置Hello Servlet的地方,增加一句
<load-on-startup>10</load-on-startup>取值範圍是1-99
即表明該Servlet會隨著Tomcat的啟動而初始化。
同時,為HelloServlet提供一個init(ServletConfig) 方法,驗證自啟動
如圖所示,在tomcat完全啟動之前,就列印了init of HelloServlet
<load-on-startup>10</load-on-startup> 中的10表示啟動順序
如果有多個Servlet都配置了自動啟動,數字越小,啟動的優先順序越高
<?xml version="1.0" encoding="UTF-8"?> <web-app> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>HelloServlet</servlet-class> <load-on-startup>10</load-on-startup> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet> <servlet-name>LoginServlet</servlet-name> <servlet-class>LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LoginServlet</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> </web-app>
import java.io.IOException; import java.util.Date; import javax.servlet.ServletConfig; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HelloServlet extends HttpServlet{ public void init(ServletConfig config){ System.out.println("init of Hello Servlet"); } public void doGet(HttpServletRequest request, HttpServletResponse response){ try { response.getWriter().println("<h1>Hello Servlet!</h1>"); response.getWriter().println(new Date().toLocaleString()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
request.getParameter(): 是常見的方法,用於獲取單值的引數
request.getParameterValues():用於獲取具有多值的引數,比如註冊時候提交的 "hobits",可以是多選的。
request.getParameterMap():用於遍歷所有的引數,並返回Map型別。
<!DOCTYPE html> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <form action="register" method="get"> 賬號 : <input type="text" name="name"> <br> 愛好 : LOL<input type="checkbox" name="hobits" value="lol"> DOTA<input type="checkbox" name="hobits" value="dota"> <br> <input type="submit" value="註冊"> </form>
import java.io.IOException; import java.util.Arrays; import java.util.Map; import java.util.Set; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class RegisterServlet extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("獲取單值引數name:" + request.getParameter("name")); String[] hobits = request.getParameterValues("hobits"); System.out.println("獲取具有多值的引數hobits: " + Arrays.asList(hobits)); System.out.println("通過 getParameterMap 遍歷所有的引數: "); Map<String, String[]> parameters = request.getParameterMap(); Set<String> paramNames = parameters.keySet(); for (String param : paramNames) { String[] value = parameters.get(param); System.out.println(param + ":" + Arrays.asList(value)); } } }
setAttribute和getAttribute可以用來在進行服務端跳轉的時候,在不同的Servlet之間進行資料共享
設定響應編碼有兩種方式
1. response.setContentType("text/html; charset=UTF-8"); 2. response.setCharacterEncoding("UTF-8");
這兩種方式都需要在response.getWriter呼叫之前執行才能生效。
他們的區別在於
不僅傳送到瀏覽器的內容會使用UTF-8編碼,而且還通知瀏覽器使用UTF-8編碼方式進行顯示。所以總能正常顯示中文
僅僅是傳送的瀏覽器的內容是UTF-8編碼的,至於瀏覽器是用哪種編碼方式顯示不管。 所以當瀏覽器的顯示編碼方式不是UTF-8的時候,就會看到亂碼,需要手動再進行一次設定。