文章目錄
來源於:how2j
頁面跳轉
-
服務端跳轉:
-
設置跳轉頁面
success.html
:-<div style="color:green">login success</div>
-
在Servlet中進行服務端跳轉的方式
request.getRequestDispatcher("success.html").forward(request, response);
-
邏輯代碼:
if ("admin".equals(name) && "123".equals(password)) { request.getRequestDispatcher("success.html").forward(request, response); }
-
服務端跳轉可以看到瀏覽器的地址依然是/login 路徑,並不會變成success.html:
-
-
客戶端跳轉
- 設置跳轉頁面
fail.html
:-<div style="color:green">login success</div>
- 在Servlet中進行服務端跳轉的方式
response.sendRedirect("fail.html");
- 邏輯代碼:
if ("admin".equals(name) && "123".equals(password)) { request.getRequestDispatcher("success.html").forward(request, response); } else{ response.sendRedirect("fail.html"); }
- 可以觀察到,瀏覽器地址發生了變化:
- 設置跳轉頁面
-
圖示:
servlet自啓動
- 有的時候會有這樣的業務需求:tomcat一啓動,就需要執行一些初始化的代碼,比如校驗數據庫的完整性等。
- 但是Servlet的生命週期是在用戶訪問瀏覽器對應的路徑開始的。如果沒有用戶的第一次訪問,就無法執行相關代碼。
- 這個時候,就需要Servlet實現自啓動 即,伴隨着tomcat的啓動,自動啓動初始化,在初始化方法init()中,就可以進行一些業務代碼的工作了。
- 在web.xml中,配置Hello Servlet的地方,增加一句
<load-on-startup>10</load-on-startup>
- 取值範圍是1-99,即表明該Servlet會隨着Tomcat的啓動而初始化;10表示啓動順序,如果有多個Servlet都配置了自動啓動,數字越小,啓動的優先級越高
- 同時,爲HelloServlet提供一個init(ServletConfig) 方法,驗證自啓動
public void init(ServletConfig config){ System.out.println("init of Hello Servlet"); }
- 驗證:
request類常見方法
- request對象的類是HttpServletRequest,提供了很多有實用價值的方法
request常見方法
request.getRequestURL(): 瀏覽器發出請求時的完整URL,包括協議 主機名 端口(如果有)"
request.getRequestURI(): 瀏覽器發出請求的資源名部分,去掉了協議和主機名"
request.getQueryString(): 請求行中的參數部分,只能顯示以get方式發出的參數,post方式的看不到
request.getRemoteAddr(): 瀏覽器所處於的客戶機的IP地址
request.getRemoteHost(): 瀏覽器所處於的客戶機的主機名
request.getRemotePort(): 瀏覽器所處於的客戶機使用的網絡端口
request.getLocalAddr(): 服務器的IP地址
request.getLocalName(): 服務器的主機名
request.getMethod(): 得到客戶機請求方式一般是GET或者POST
- 驗證代碼:
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = request.getParameter("name");
String password = request.getParameter("password");
System.out.println("瀏覽器發出請求時的完整URL,包括協議 主機名 端口(如果有): " + request.getRequestURL());
System.out.println("瀏覽器發出請求的資源名部分,去掉了協議和主機名: " + request.getRequestURI());
System.out.println("請求行中的參數部分: " + request.getQueryString());
System.out.println("瀏覽器所處於的客戶機的IP地址: " + request.getRemoteAddr());
System.out.println("瀏覽器所處於的客戶機的主機名: " + request.getRemoteHost());
System.out.println("瀏覽器所處於的客戶機使用的網絡端口: " + request.getRemotePort());
System.out.println("服務器的IP地址: " + request.getLocalAddr());
System.out.println("服務器的主機名: " + request.getLocalName());
System.out.println("得到客戶機請求方式: " + request.getMethod());
String html = null;
if ("admin".equals(name) && "123".equals(password))
html = "<div style='color:green'>登錄成功</div>";
else
html = "<div style='color:red'>登錄失敗</div>";
response.setContentType("text/html; charset=UTF-8");
PrintWriter pw = response.getWriter();
pw.println(html);
}
request獲取參數
request.getParameter(): 是常見的方法,用於獲取單值的參數
request.getParameterValues(): 用於獲取具有多值的參數,比如註冊時候提交的 "hobits",可以是多選的。
request.getParameterMap(): 用於遍歷所有的參數,並返回Map類型。
- 本例準備了一個註冊的例子,包括一個註冊頁面 register.html
服務端的 RegisterServlet,分別演示了獲取單值參數,多值參數以及遍歷所有的參數 - register.html:
<!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>
- RegisterServlet.java:
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));
}
}
- 驗證:
request獲取頭信息:
request.getHeader() 獲取瀏覽器傳遞過來的頭信息。
比如getHeader("user-agent") 可以獲取瀏覽器的基本資料,這樣就能判斷是firefox、IE、chrome、或者是safari瀏覽器
request.getHeaderNames() 獲取瀏覽器所有的頭信息名稱,根據頭信息名稱就能遍歷出所有的頭信息
- 在本例,修改HelloServlet,使其獲取頭信息
訪問HelloServlet獲取如下頭信息:
host: 主機地址
user-agent: 瀏覽器基本資料
accept: 表示瀏覽器接受的數據類型
accept-language: 表示瀏覽器接受的語言
accept-encoding: 表示瀏覽器接受的壓縮方式,是壓縮方式,並非編碼
connection: 是否保持連接
cache-control: 緩存時限
- HelloServlet.java:
public class HelloServlet extends HttpServlet{
public void init(ServletConfig config){
System.out.println("init of Hello Servlet");
}
public void doGet(HttpServletRequest request, HttpServletResponse response){
Enumeration<String> headerNames= request.getHeaderNames();
while(headerNames.hasMoreElements()){
String header = headerNames.nextElement();
String value = request.getHeader(header);
System.out.printf("%s\t%s%n",header,value);
}
try {
response.getWriter().println("<h1>Hello Servlet!</h1>");
response.getWriter().println(new Date().toLocaleString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
- 驗證:
服務端傳參
- setAttribute和getAttribute可以用來在進行服務端跳轉的時候,在不同的Servlet之間進行數據共享,後面再講
response常見用法
response是HttpServletResponse的實例,用於提供給瀏覽器的響應信息
設置響應內容
- 通過response.getWriter(); 獲取一個PrintWriter 對象
- 可以使用println(),append(),write(),format()等等方法設置返回給瀏覽器的html內容。
- 驗證代碼
public void doGet(HttpServletRequest request, HttpServletResponse response){
try {
PrintWriter pw= response.getWriter();
pw.println("<h1>Hello Servlet</h1>");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
設置響應格式
response.setContentType("text/html");
- “text/html” 是即格式 ,在request獲取頭信息 中對應的
request.getHeader("accept")
. - “text/html” 是存在的,表示瀏覽器可以識別這種格式,如果換一個其他的格式, 比如 “text/lol” ,瀏覽器不能識別,那麼打開此servlet就會彈出一個下載的對話框。這樣的手段也就常常用於實現下載功能
- 驗證代碼:
public void doGet(HttpServletRequest request, HttpServletResponse response) {
try {
PrintWriter pw = response.getWriter();
pw.println("<h1>Hello Servlet</h1>");
response.setContentType("text/lol");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
- res:
設置響應編碼
- 有兩種方法:
response.setContentType("text/html; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
- 這兩種方式都需要在response.getWriter調用之前執行才能生效。
- 他們的區別在於:
response.setContentType("text/html; charset=UTF-8");
不僅發送到瀏覽器的內容會使用UTF-8編碼,而且還通知瀏覽器使用UTF-8編碼方式進行顯示。所以總能正常顯示中文response.setCharacterEncoding("UTF-8");
僅僅是發送的瀏覽器的內容是UTF-8編碼的,至於瀏覽器是用哪種編碼方式顯示不管。 所以當瀏覽器的顯示編碼方式不是UTF-8的時候,就會看到亂碼,需要手動再進行一次設置。
- 驗證代碼:
public void doGet(HttpServletRequest request, HttpServletResponse response) {
try {
// response.setContentType("text/html; charset=UTF-8");
// response.setCharacterEncoding("UTF-8");
PrintWriter pw = response.getWriter();
pw.println("<h1>第一次 使用 Servlet</h1>");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
- res:
response.setCharacterEncoding("UTF-8");
public void doGet(HttpServletRequest request, HttpServletResponse response) {
try {
// response.setContentType("text/html; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter pw = response.getWriter();
pw.println("<h1>第一次 使用 Servlet</h1>");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
- res:
- 而當我改變瀏覽器的解碼方式:
response.setContentType("text/html; charset=UTF-8");
public void doGet(HttpServletRequest request, HttpServletResponse response) {
try {
response.setContentType("text/html; charset=UTF-8");
// response.setCharacterEncoding("UTF-8");
PrintWriter pw = response.getWriter();
pw.println("<h1>第一次 使用 Servlet</h1>");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
- res:
不使用緩存
使用緩存可以加快頁面的加載,降低服務端的負擔。但是也可能看到過時的信息,可以通過如下手段通知瀏覽器不要使用緩存
response.setDateHeader("Expires",0 );
response.setHeader("Cache-Control","no-cache");
response.setHeader("pragma","no-cache");