文章目錄
1. response
response對象的功能分爲以下四種:
- 設置響應頭信息;
- 發送狀態碼;
- 設置響應正文;
- 重定向;
1.1 設置響應頭信息
response.setHeader(“content-type”, “text/html;charset=utf-8”)
// 設置content-type響應頭,該頭的作用是告訴瀏覽器響應內容爲html類型,編碼爲utf-8。而且同時會設置response的字符流編碼爲utf-8,即response.setCharaceterEncoding(“utf-8”);
response.setHeader("Refresh","5; URL=http://www.itcast.cn")
// 5秒後自動跳轉到傳智主頁
1.2 發送狀態碼及其他方法
response.setContentType("text/html;charset=utf-8"):等同與調用response.setHeader(“content-type”, “text/html;charset=utf-8”);
response.setCharacterEncoding(“utf-8”):設置字符響應流的字符編碼爲utf-8;
response.setStatus(200):設置狀態碼;
response.sendError(404, “您要查找的資源不存在”):當發送錯誤狀態碼時,Tomcat會跳轉到固定的錯誤頁面去,但可以顯示錯誤信息。
1.3 設置響應正文
response是響應對象,向客戶端輸出響應正文(響應體)可以使用response的響應流,repsonse一共提供了兩個響應流對象:
PrintWriter out = response.getWriter():獲取字符流對象;
ServletOutputStream out = response.getOutputStream():獲取字節流對象;
response.getWriter()是PrintWriter類型,所以它有緩衝區,緩衝區的默認大小爲8KB。
如果希望響應數據馬上發送給客戶端,需要調用response.flushBuffer()
方法來手動刷新緩衝區;
1.4 重定向
- 重定向是兩次請求;
- 重定向的URL可以是其他應用,不侷限於當前應用;
- 重定向的響應頭爲302,並且必須要有Location響應頭;
- 重定向就不要再使用response.getWriter()或response.getOutputStream()輸出數據,不然可能會出現異常;
2. request
request的功能:
- 封裝了請求頭數據;
- 封裝了請求正文數據,如果是GET請求,那麼就沒有正文;
- request是一個域對象,可以把它當成Map來添加獲取數據;
- request提供了請求轉發和請求包含功能。
2.1 請求頭
String getHeader(String name):獲取指定名稱的請求頭;
Enumeration getHeaderNames():獲取所有請求頭名稱;
int getIntHeader(String name):獲取值爲int類型的請求頭。
2.2 請求參數
String getParameter(String name):通過指定名稱獲取參數值;
String[] getParameterValues(String name):當多個參數名稱相同時,可以使用方法來獲取;
Enumeration getParameterNames():獲取所有參數的名字;
Map getParameterMap():獲取所有參數封裝到Map中,其中key爲參數名,value爲參數。
2.3 域對象
request是域對象!一個請求只會創建一個request對象。
Servlet中三大域對象:request、session、application。
void setAttribute(String name, Object value)
Object getAttribute(String name)
void removeAttribute(String name)
Enumeration getAttributeNames()
2.4 請求轉發和請求包含
(1)一個請求跨多個Servlet,需要使用轉發和包含。
RequestDispatcher rd = request.getRequestDispatcher("/MyServlet"); 使用request獲取RequestDispatcher對象,方法的參數是被轉發或包含的Servlet的Servlet路徑
請求轉發:rd.forward(request,response);
請求包含:rd.include(request,response);
- 請求轉發:由下一個Servlet完成響應體!當前Servlet可以設置響應頭!(留頭不留體)
- 請求包含:由兩個Servlet共同完成響應體!(都留)
- 無論是請求轉發還是請求包含,都在一個請求範圍內!使用同一個request和response!
(2)請求轉發與請求包含比較
- 轉發留頭不留體,包含都可以留;
- 請求包含大多是應用在JSP頁面中,完成多頁面的合併;
- 請求轉發大多是應用在Servlet中,轉發目標大多是JSP頁面;
(3)請求轉發與重定向比較
- 請求轉發是一個請求,而
重定向是兩個請求
; - 請求轉發後瀏覽器地址欄不會有變化,而重定向會有變化,因爲重定向是兩個請求;
- 請求轉發的目標只能是本應用中的資源,重定向的目標可以是其他應用;
- 請求轉發對AServlet和BServlet的請求方法是相同的,即要麼都是GET,要麼都是POST,因爲請求轉發是一個請求;
- 重定向的第二個請求一定是GET;
- 請求轉發是服務器端行爲,只需給出轉發的Servlet路徑,而重定向需要給出requestURI,即包含項目名!
- 請求轉發和重定向效率是轉發高!因爲是一個請求!
- 需要在下一個Servlet中獲取request域中的數據,必須要使用轉發!
3.編碼
3.1 請求編碼
-
直接在地址欄給出請求
不同瀏覽器使用不同的編碼,所以這是不確定的!IE和FireFox:使用GB2312;而Chrome:使用UTF-8; -
在頁面發出請求
頁面是服務器發送到客戶端瀏覽器的,所以這個頁面本身的編碼由服務器決定。
<head>
<title>index.html</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
- get請求解讀編碼
request.getParameter()獲取的數據是被服務器誤認爲ISO-8859-1編碼的,所以需要使用ISO-8859-1解碼再編碼成需要的格式。
String name = request.getParameter(“name”);
name = new String(name.getBytes(“iso-8859-1”), “utf-8”);
- post請求解讀編碼
(1)先指定編碼:request.setCharacterEncoding();再讀取數據:reuqest.getParameter()
(1)但如果沒有指定編碼,那麼默認還是使用ISO-8859-1來解讀。
request.setCharacterEncoding(“utf-8”);
String name = request.getParameter(“name”);
3.2 響應編碼
服務器默認的相應編碼是ISO-8859-1,使用response.getWriter()發送數據之前,一定要設置response的編碼:
response.setCharacterEncoding(“utf-8”);
同時需要通知瀏覽器使用的解碼方式:
response.setContentType(“text/html;charset=utf-8”);
在靜態頁面中,使用<meta>
來設置content-type響應頭,例如:
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
3.3 URL編碼
特殊字符需要先轉換成URL編碼格式,再發送給服務器。
表單自動使用URL編碼,只有get請求需要手動設置編碼:
這裏使用JS修改:
<script type="text/javascript">
function _go() {
location = "/day05_2/AServlet?name=" + encodeURIComponent("傳智+播客");
}
</script>
<a href="javascript:_go();">鏈接</a>
4.路徑問題
4.1. 客戶端路徑和服務器端路徑
- 客戶端路徑需要給出應用名稱,例如:/day05_1/AServlet
- 服務器端路徑無需給出應用名稱,例如:/AServlet
4.2. 客戶端路徑
1). 頁面中都是客戶端路徑:
<a>
的href:如果不以“/”開頭,那麼相對當前.html頁面所在路徑<form>
的action<img>
的src
2). 重定向也是客戶端路徑:
以“/”開頭:相對當前主機,例如:http://localhost:8080/
,所以需要自己手動添加項目名
response.sendRedirect("/day05_1/BServlet");
相當於:http://localhost:8080/day05_1/BServlet
4.3. 服務器端路徑
(1)<url-pattern>
:也叫Servlet路徑
- 要麼以
“*”
開關,要麼爲“/”
開頭
(2)請求轉發和請求包含
- 以“/”開頭:相對當前項目路徑,例如:http://localhost:8080/項目名/
request.getRequestdispacher("/BServlet")
==>文件地址 http://localhost:8080/項目名/BServlet.java
- 不以“/”開頭:相對當前Servlet路徑。
- request.getRequestdispacher("/BServlet");,
假如當前Servlet是:http://localhost:8080/項目名/servlet/
AServlet,
就是http://localhost:8080/項目名/servlet/
BServlet
(3)ServletContext獲取資源等
相對當前項目目錄,即當然index.jsp所在目錄(http://localhost:8080/項目名)
4.4 獲取類路徑資源
可以通過Class類的對象來獲取類路徑下的資源,對應JavaWeb應用的類路徑就是classes目錄下的資源。
類路徑對一個JavaWeb項目而言,就是/WEB-INF/classes和/WEB-INF/lib/每個jar包!
常見方式:
-
Class類的getResourceAsStream(String path):
路徑以“/”開頭,相對classes路徑;
路徑不以“/”開頭,相對當前.class文件所在路徑,例如在cn.itcast.servlet.MyServlet中執行,那麼相對/classes/cn/itcast/servlet/路徑; -
ClassLoader類的getResourceAsStream(String path):
相對classes路徑;
例如:
InputStream in = this.getClass().getResourceAsStream("/xxx.txt"); // 在classes文件夾內
System.out.println(IOUtils.toString(in));
InputStream in = this.getClass().getClassLoader().getResourceAsStream("xxx.txt");// 在classes文件夾
System.out.println(IOUtils.toString(in));