1. 程式人生 > >Java Web(5)-Servlet詳解(下)

Java Web(5)-Servlet詳解(下)

## 一、HttpServletRequest 類 ### 1. HttpServletRequest 類作用? 每次只要有請求進入 Tomcat 伺服器,Tomcat 伺服器就會把請求過來的 HTTP 協議資訊解析好封裝到 Request 物件中。 然後傳遞到 service 方法(doGet 和 doPost)中給我們使用,可以通過 HttpServletRequest 物件,獲取到所有請求的 資訊 ### 2. HttpServletRequest 類的常用方法 - getRequestURI() 獲取請求的資源路徑 - getRequestURL() 獲取請求的統一資源定位符(絕對路徑) - getRemoteHost() 獲取客戶端的 ip 地址 - getHeader() 獲取請求頭 - getParameter() 獲取請求的引數 - getParameterValues() 獲取請求的引數(多個值的時候使用) - getMethod() 獲取請求的方式 GET 或 POST - setAttribute(key, value); 設定域資料 - getAttribute(key); 獲取域資料 - getRequestDispatcher() 獲取請求轉發物件 具體如下: 首先把環境建好,配置好web.xml ,然後在類中 ```java package com.md.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author MD * @create 2020-07-25 8:18 */ public class RequestAPIServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println(req.getRequestURI());// /04_Servlet/requestAPIServlet System.out.println(req.getRequestURL()); //http://localhost:8080/04_Servlet/requestAPIServlet System.out.println(req.getRemoteHost());//127.0.0.1 System.out.println(req.getHeader("User-Agent"));//Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36 System.out.println(req.getMethod());//GET } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } } ``` 對應的web.xml ```xml RequestAPIServlet com.md.servlet.RequestAPIServlet RequestAPIServlet /requestAPIServlet ``` ### 3. 獲取請求引數 首先在web下面建立html檔案,如下 ```html Title 使用者名稱:
密碼:
愛好:C++ Java Python ``` 然後是對應的java程式碼,以及配置的web.xml(和上面的類似) ```java /** * @author MD * @create 2020-07-25 8:31 */ public class ParameterServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("------------doGet--------------"); // 獲取請求的引數 String username = req.getParameter("username"); String password = req.getParameter("password"); // String hobby = req.getParameter("hobby"); // 當有多個值的時候 String [] hobby = req.getParameterValues("hobby"); System.out.println("使用者名稱:"+username); System.out.println("密碼:"+password); System.out.println("愛好:"+ Arrays.asList(hobby)); } } ``` ### 4. 中文亂碼 使用post請求的時候,如果使用者名稱輸入的是中文,則會出現中文亂碼的情況,所以需要這樣設定 ```java public class ParameterServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 在post的時候注意設定字符集,要不中文亂碼 // 只有在獲取請求引數呼叫之前使用才有效 req.setCharacterEncoding("UTF-8"); System.out.println("------------doPost--------------"); // 獲取請求的引數 String username = req.getParameter("username"); String password = req.getParameter("password"); // String hobby = req.getParameter("hobby"); // 當有多個值的時候 String [] hobby = req.getParameterValues("hobby"); System.out.println("使用者名稱:"+username); System.out.println("密碼:"+password); System.out.println("愛好:"+ Arrays.asList(hobby)); } } ``` ### 5. 請求轉發 什麼是請求的轉發? 請求轉發是指伺服器收到請求後,從一次資源跳轉到另一個資源的操作叫請求轉發 **請求轉發的特點:** - 瀏覽器位址列沒有改變 - 一次請求 - 共享Request域中的資料 - 可以轉發到WEB-INF目錄下 - 不可以訪問工程以外的資源 ![](https://img2020.cnblogs.com/blog/1212924/202007/1212924-20200728220347158-702935334.png) 例子如下:通過訪問Servlet1然後轉發到Servlet2去 ```java public class Servlet1 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // http://localhost:8080/04_Servlet/servlet1?username=abc // 1. 獲取請求的引數 String username = req.getParameter("username"); System.out.println("在Servlet1中獲取到的請求引數:"+username); // 在Servlet1中獲取到的請求引數:abc // 2. 把獲取到的資料傳遞,也可以自定義引數傳遞 // req.setAttribute("username" , username); req.setAttribute("key","我來自Servlet1"); // 3. 轉發 // 地址必須以 /開頭 ,這個地址也是在web.xml中配置對應的你要去的 RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2"); requestDispatcher.forward(req,resp); // 或者可以直接這樣 req.getRequestDispatcher("/servlet2").forward(req,resp); } } ``` 對應的web.xml就不展示了,都類似 ```java /** * @author MD * @create 2020-07-25 8:57 */ public class Servlet2 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1. 獲取請求的引數 String username = req.getParameter("username"); System.out.println("在Servlet2中獲取到的請求引數:"+username);//在Servlet2中獲取到的請求引數:abc // 2. 檢視從Servlet1中傳遞的引數 Object key = req.getAttribute("key"); System.out.println("Servlet1中傳來的引數:"+key);//Servlet1中傳來的引數:我來自Servlet1 // 3. 處理自己的業務 System.out.println("正在處理Servlet2的業務");//正在處理Servlet2的業務 } } ``` ### 6. base標籤 ![](https://img2020.cnblogs.com/blog/1212924/202007/1212924-20200728220357857-770722003.png) 所以在html檔案中,跳轉的時候若使用相對路徑,指定相對的那個路徑 ```html Title
這是a目錄下的b目錄下的c.html頁面 跳到首頁 ``` 開發中儘量使用絕對路徑,實在不行就使用base+相對路徑 ### 7. web中 / 斜槓的不同意義 在web中 / 是一種絕對路徑 1. / 斜槓被瀏覽器解析,得到的地址就是 http://ip:port `斜槓 ` 2. / 斜槓 如果被伺服器解析,得到的地址是:http://ip:port/工程路徑 - `/servlet1` - servletContext.getRealPath(“/”); - request.getRequestDispatcher(“/”); 3. 特殊情況: response.sendRediect(“/”); 把斜槓傳送給瀏覽器解析。得到 http://ip:port/ ## 二、HttpServletResponse 類 ### 1. HttpServletResponse 類的作用 HttpServletResponse 類和 HttpServletRequest 類一樣。 每次請求進來,Tomcat 伺服器都會建立一個 Response 物件傳 遞給 Servlet 程式去使用。HttpServletRequest 表示請求過來的資訊,HttpServletResponse 表示所有響應的資訊, 我們如果需要設定返回給客戶端的資訊,都可以通過 HttpServletResponse 物件來進行設定 ### 2. 兩個輸出流 | 字元流 | getWriter() | 用於傳字串(常用) | | ------ | ----------------- | ------------------------ | | 位元組流 | getOutputStream() | 用於下載(傳遞二進位制資料) | ### 3. 如何往客戶端回傳資料 首先還是先建立一個servlet,配置對應的web.xml 注意中文的亂碼情況 ```java package com.md.servlet; /** * @author MD * @create 2020-07-25 9:57 */ public class ResponseIOServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // System.out.println(resp.getCharacterEncoding());//ISO-8859-1 // // // 設定伺服器字符集為 // resp.setCharacterEncoding("UTF-8"); // // 此時若瀏覽器沒有使用UTF-8中文還是亂碼,這個時候需要 // // 通過設定響應頭,使得瀏覽器也使用UTF-8字符集 // resp.setHeader("Content-Type","text/html; charset=UTF-8"); // 或者直接可以這樣寫,自動設定伺服器字符集和瀏覽器響應頭 // 方法一定要流獲取之前先呼叫,通常放在最上面就行 resp.setContentType("text/html; charset=UTF-8"); // 需求:往客戶端回傳字串資料 PrintWriter writer = resp.getWriter(); writer.write("response"); writer.write("越過山丘,"); } } ``` ### 4. 請求重定向 請求重定向,是指客戶端給伺服器發請求,然後伺服器告訴客戶端說。我給你一些地址。你去新地址訪問。叫請求 重定向(因為之前的地址可能已經被廢棄) **請求重定向的特點:** - 瀏覽器的地址會發生改變 - 兩次請求 - 不能共享Request域中的資料 - 不能訪問WEB-INF下的資源 - 可以訪問工程外的資源 ![](https://img2020.cnblogs.com/blog/1212924/202007/1212924-20200728220433607-871841761.png) 例子如下:訪問Response1重定向到Response2 ```java /** * @author MD * @create 2020-07-25 10:15 */ public class Response1 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("Response 1 "); // // 設定響應狀態碼,表示重定向 // resp.setStatus(302); // // // 設定響應頭,說明新的地址,和web.xml裡的要對應 // resp.setHeader("Location","http://localhost:8080/04_Servlet/response2"); // 推薦使用 resp.sendRedirect("http://localhost:8080/04_Servlet/response2"); } } //----------------------------------- public class Response2 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("Response 2 "); resp.getWriter().write("Response2 result !"); } } ``` 對應的web.xml ```xml Response1
com.md.servlet.Response1
Response1 /response1 Response2 com.md.servlet.Response2 Response2 /response2