Request&Response Request 獲取請求數據 Response 設置響應數據 1、Request 1.1、Request繼承體系 1、Tomcat需要解析請求數據,封裝為request對象,並且創建request對象傳遞到service方法中 2、使用request對象,查閱Jav ...
Request&Response
- Request
- 獲取請求數據
- Response
- 設置響應數據
1、Request
1.1、Request繼承體系
- 1、Tomcat需要解析請求數據,封裝為request對象,並且創建request對象傳遞到service方法中
- 2、使用request對象,查閱JavaEE API文檔的
HttpServletRequest
介面
1.2、Request獲取請求數據
1.2.1、獲取請求數據的方法
-
請求行:GET /request-response-demo/req1?username=zhangsan HTTP/1.1
-
方法 說明 數據 String getMethod() 獲取請求方式 GET String getContextPath() 獲取虛擬路徑(項目訪問路徑) /request-response-demo StringBuffer getRequestURL() 獲取URL(統一資源定位符) http://localhost:8080/request-response-demo/req1 String getRequestURI() 獲取URI(統一資源定位符) /request-response-demo/req1 String getQueryString() 獲取請求參數(GET方式) username=zhangsan&password=123
-
-
請求頭:User-Agent: Mozilla/5.0 Chrome/91.0.4472.106
String getHeader(String name)
:根據請求頭名稱,獲取值
-
請求體:username=superbaby&password=123
ServletInputStream getInputStream()
:獲取位元組輸入流BufferedReader getReader()
:獲取字元輸入流
1.2.2、通用方式獲取請求參數
- 請求參數獲取方式
- GET方式
- String getQueryString()
- POST方式
- BufferedReader getReader()
- GET方式
- 思考
- 這裡的GET請求方式和POST請求方式,區別主要在於獲取請求參數的方式不一樣
- 那麼是否有一種統一獲取請求參數的方式,從而統一doGet和doPost方法內的代碼?
- 在Tomcat源碼中,實現了一個在獲取請求方式的時候,將參數賦值給了同一個成員變數param,使得doGet和doPost方法內的請求參數方式的代碼有了統一的可能
-
Map<String,String[]> getParameterMap()
:獲取所有參數Map集合String getParameter(String name)
:根據名稱獲取參數值(單個值)String[] getParameterValues(String name)
:根據名稱獲取參數值(數組)
1.2.3、請求參數中文亂碼處理
- Tomcat 8.0 之後,GET請求亂碼的問題已經被解決,設置預設的編碼方式為UTF-8,其他Tomcat的預設編碼都為 ISO-8859-1;
- Request解決POST請求參數中文亂碼
- 給POST方法設置輸入流的編碼
request.setCharacterEncoding("UTF-8")
- 給POST方法設置輸入流的編碼
- URL編碼
- 1.將字元串按照編碼方式轉為二進位
- 2.每個位元組轉為2個16進位數併在前面加上%
1.3、Request請求轉發
- 請求轉發(forward):一種在伺服器內部的資源跳轉方式
- 實現方式
request.getRequestDispatcher("資源B路徑").forward(request, response);
- 請求轉發資源間共用數據:使用Request對象
void setAttribute(String name, Object o)
:存儲數據到request域中Object getAttribute(String name)
:根據key,獲取值void removeAttribute(String name)
:根據key,刪除鍵值對
- 請求轉發的特點
- 瀏覽器地址欄路徑不發生變化
- 只能轉發到當前伺服器的內部資源
- 一次請求,可以在轉發資源間使用request共用數據
2、Response
- Request:使用request對象來獲取請求數據
- Response:使用response對象來設置響應數據
2.1、Response繼承體系
2.2、Response設置響應數據
- 響應數據分為3個部分
- 響應行
HTTP/1.1 200 OK
void setStatus(int sc)
:設置響應狀態
- 響應頭
Content-Type:text/html
void setHeader(String name, String value)
:設置響應頭鍵值對
- 響應體
<html><head></head><body></body></html>
PrintWriter getWriter()
:獲取字元輸出流ServletOutputStream getOutputStream()
:獲取位元組輸出流
- 響應行
2.3、Response重定向
- 重定向概念
- 跳轉到下一個頁面,不需要傳遞數據,使用重定向
- 是一種資源跳轉方式
- 實現方式
- 方式1
response.setStatus(302);
response.setHeader("location", "資源B的路徑");
- 方式2
response.sendRedirect("資源B的路徑");
- 方式1
- 重定向的特點
- 瀏覽器地址欄發生變化
- 可以重定向到任意位置的資源(伺服器內部、外部均可)
- 再次請求,不能在多個資源使用request共用數據
2.4、Response響應字元數據
- 實現方式
- 1.通過Response對象獲取字元輸出流
PrintWriter writer = response.getWriter();
- 2.輸出數據
writer.write("aaa");
- 1.通過Response對象獲取字元輸出流
- 註意事項
- 該流不需要關閉,隨著響應結束,response對象銷毀,由伺服器關閉
- 中文數據亂碼,原因是通過Response獲取的字元輸出流預設編碼跟Tomcat的預設編碼一樣都是:ISO-8859-1
- 解決方式
response.setContentType("text/html;charset=utf-8");
- 解決方式
2.5、Response響應位元組數據
-
實現方式
- 1.通過Response對象獲取位元組輸出流
ServletOutputStream outputStream = response.getOutputStream();
- 2.寫數據
outputStream.write(位元組數據);
- 1.通過Response對象獲取位元組輸出流
-
IOUtils
工具類的使用-
添加依賴
-
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId <version>2.6</version> </dependency>
-
-
IOUtils.copy(輸入流,輸出流);
-
3、額外註意事項
3.1、路徑問題
- 明確路徑誰使用?
- 瀏覽器使用
/
開頭是絕對路徑,會缺少項目訪問路徑- 不加
/
是相對路徑,使用當前訪問路徑作為參照物,不會缺少項目訪問路徑 - 瀏覽器使用的時候不加
/
- 伺服器使用
- 不加
/
- 不加
- 瀏覽器使用
4、使用Tomcat實現用戶登錄和註冊功能
-
LoginServlet
類-
package com.coolman.servlet; import com.coolman.mapper.UserMapper; import com.coolman.pojo.User; import com.coolman.utils.MybatisUtils; import org.apache.ibatis.session.SqlSession; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/loginServlet") public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 在這裡處理請求 // 處理html表單的POST請求發送數據,中文時存在的編碼問題 request.setCharacterEncoding("utf-8"); // 1. 獲取參數 String username = request.getParameter("username"); String password = request.getParameter("password"); // 2. 連接資料庫 SqlSession sqlSession = MybatisUtils.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.selectUser(username, password); // 3. 判斷表中是否存在該用戶信息 // 輸出提示信息之前,需要解決response返迴響應數據可能出現中文亂碼的問題 response.setContentType("text/html;charset=utf-8"); PrintWriter writer = response.getWriter(); if (user != null) { // 輸出字元流信息 writer.println("登錄成功!"); // writer.println("<style>window.alert('恭喜您登錄成功!')</style>"); } else { writer.println("登錄失敗!"); // writer.println("<style>window.alert('賬號密碼錯誤,登錄失敗!')</style>"); } sqlSession.close(); } }
-
-
RegisterServlet
類-
package com.coolman.servlet; import com.coolman.mapper.UserMapper; import com.coolman.pojo.User; import com.coolman.utils.MybatisUtils; import org.apache.ibatis.session.SqlSession; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/registerServlet") public class RegisterServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 在這裡處理請求 // 處理POST請求,表單返回的數據可能出現亂碼的問題 request.setCharacterEncoding("utf-8"); // 獲取參數 String username = request.getParameter("username"); String password = request.getParameter("password"); // 連接資料庫 SqlSession sqlSession = MybatisUtils.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 查詢該信息是否存在資料庫 User user = mapper.selectUserByUsername(username); // 解決response響應的數據可能出現亂碼的問題 response.setContentType("text/html;charset=utf-8"); // 獲取字元輸出流 PrintWriter writer = response.getWriter(); // 考慮存在和不存在問題 if (user != null) { // 如果用戶存在 writer.println("該用戶已經存在,請重新註冊!"); } else { // 如果用戶不存在,那麼就創建這個用戶 User userNew = new User(); userNew.setUsername(username); userNew.setPassword(password); mapper.addUser(userNew); sqlSession.commit(); writer.println("註冊成功!"); } sqlSession.close(); } }
-