日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

RequestResponse

發布時間:2024/8/1 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RequestResponse 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Request&Response-授課

http協議特點

? 基于請求和響應

? 端口80

? 底層是TCP

servlet

? 生命周期 init service destory

? 創建時機:默認是第一次訪問創建該servlet的對象,可以通過load-on-startup

? servlet是不是單例:單例

? 是線程安全的嗎?不是

? urlpattern的三種匹配方式:完全匹配 路徑匹配 后綴名

? ServletContext對象

? 獲取 request. super.

? 方法 getMimeType() getRealPath() getInitParameter() setAttrubite getAttribute

? 生命周期 隨著tomcat的啟動而創建,停止而銷毀。里面的數據被所有的servlet共享

1 響應對象

1.1 響應對象概述

1.1.1 關于響應

響應,它表示了服務器端收到請求,同時也已經處理完成,把處理的結果告知用戶。簡單來說,指的就是服務器把請求的處理結果告知客戶端。在B/S架構中,響應就是把結果帶回瀏覽器。

響應對象,顧名思義就是用于在JavaWeb工程中實現上述功能的對象。

1.1.2 常用響應對象

響應對象也是是Servlet規范中定義的,它包括了協議無關的和協議相關的。

協議無關的對象標準是:ServletResponse接口

協議相關的對象標準是:HttpServletResponse接口

類結構圖如下:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-yBenB06v-1609509272860)(assets/響應類視圖.png)]

我們課程中涉及的響應對象都是和HTTP協議相關的。即使用的是HttpServletResponse接口的實現類。

這里有些同學可能會產生疑問,我們在使用Servlet時,需要定義一個類,然后實現Servlet接口(或者繼承它的實現類)?,F在我們想要實現響應功能,要不要定義一個類,然后實現HttpServletResponse接口呢?

此問題的答案是否定的,我們無需這么做。我們只需要在自己寫的Servlet中直接使用即可,因為這個對象的實現類是由Tomcat提供的,無須我們自定義。同時它還會幫我們把對象創建出來并傳入doGet和doPost方法中。

1.2 常用方法介紹

在HttpServletResponse接口中提供了很多方法,接下來我們通過API文檔,來了解一下這些方法。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-3bqviq5h-1609509272863)(assets/響應方法詳解.png)]

常用狀態碼:

狀態碼說明
200執行成功
302它和307一樣,都是用于重定向的狀態碼。只是307目前已不再使用
304請求資源未改變,使用緩存。
400請求錯誤。最常見的就是請求參數有問題
404請求資源未找到
405請求方式不被支持
500服務器運行內部錯誤

狀態碼首位含義:

狀態碼說明
1xx消息
2xx成功
3xx重定向
4xx客戶端錯誤
5xx服務器錯誤

1.3 響應對象的使用示例

1.3.1 響應-字節流輸出中文問題

public class ResponseDemo1 extends HttpServlet {

/*** 演示字節流輸出的亂碼問題*/ public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {/*** 問題:* String str = "字節流中文亂碼問題";* 使用字節流輸出,會不會產生中文亂碼?* 答案:* 會產生亂碼* 原因:* String str = "字節流中文亂碼問題"; 在保存時用的是IDEA創建文件使用的字符集UTF-8。* 到瀏覽器上顯示,chrome瀏覽器和ie瀏覽器默認的字符集是GB2312(其實就是GBK),存和取用的不是同一個碼表,就會產生亂碼。** 引申:* 如果產生了亂碼,就是存和取用的不是同一個碼表* 解決辦法:* 把存和取的碼表統一。*/String str = "字節流輸出中文的亂碼問題";//UTF-8的字符集,此時瀏覽器顯示也需要使用UTF-8的字符集。//1.拿到字節流輸出對象ServletOutputStream sos = response.getOutputStream();/*** 解決辦法:* 第一種解決辦法:* 修改瀏覽器的編碼,使用右鍵——編碼——改成UTF-8。(不推薦使用,我們的應用盡量不要求用戶取做什么事情)* ie和火狐瀏覽器可以直接右鍵設置字符集。而chrome需要安裝插件,很麻煩。* 第二種解決辦法: (不建議使用,因為不好記)* 向頁面上輸出一個meta標簽,內容如下: <meta http-equiv="content-type" content="text/html;charset=UTF-8">* 其實它就是指揮了瀏覽器,使用哪個編碼進行顯示。* 第三種解決辦法:* 設置響應消息頭,告知瀏覽器響應正文的MIME類型和字符集* response.setHeader("Content-Type","text/html;charset=UTF-8");* 第四種解決辦法:我們推薦使用的辦法* 它的本質就是設置了一個響應消息頭* response.setContentType("text/html;charset=UTF-8");*///第二種解決辦法:sos.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'>".getBytes());//第三種解決辦法:response.setHeader("Content-Type","text/html;charset=UTF-8");//第四種解決辦法:response.setContentType("text/html;charset=UTF-8");//2.把str轉換成字節數組之后輸出到瀏覽器sos.write(str.getBytes("UTF-8")); }public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response); }

}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-wKI8MU1m-1609509272864)(assets/ResponseDemo1.png)]### 1.3.2 響應-字符流輸出中文問題public class ResponseDemo2 extends HttpServlet {/*** 字符流輸出中文亂碼* @param request* @param response* @throws ServletException* @throws IOException*/public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {String str = "字符流輸出中文亂碼";//response.setCharacterEncoding("UTF-8");//設置響應正文的MIME類型和字符集response.setContentType("text/html;charset=UTF-8");//1.獲取字符輸出流PrintWriter out = response.getWriter();//2.使用字符流輸出中文/*** 問題:* out.write(str); 直接輸出,會不會產生亂碼* 答案:* 會產生亂碼* 原因:* 存用的什么碼表:UTF-8* 在瀏覽器取之前,字符流PrintWriter已經獲取過一次了,PrintWriter它在取的時候出現了亂碼。* 瀏覽器取默認用的是GBK。(本地系統字符集)** UTF-8(存)————>PrintWriter ISO-8859-1(取) 亂* PrintWirter ISO-8859-1(存)————>瀏覽器 GBK(取) 亂** 解決辦法:* 改變PrintWriter的字符集,PrintWriter是從response對象中獲取的,其實設置response的字符集。* 注意:設置response的字符集,需要在拿流之前。* response.setCharacterEncoding("UTF-8");** response.setContentType("text/html;charset=UTF-8");* 此方法,其實是做了兩件事:* 1.設置響應對象的字符集(包括響應對象取出的字符輸出流)* 2.告知瀏覽器響應正文的MIME類型和字符集*/out.write(str);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);} }

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-5wB2FXIX-1609509272866)(assets/ResponseDemo2.png)]

1.3.3 響應-生成驗證碼

public class ResponseDemo3 extends HttpServlet {

/*** 輸出圖片* @param request* @param response* @throws ServletException* @throws IOException*/ public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {int width = 200;int height = 35;/*** 實現步驟:* 1.創建圖像內存對象* 2.拿到畫筆* 3.設置顏色,畫矩形邊框* 4.設置顏色,填充矩形* 5.設置顏色,畫干擾線* 6.設置顏色,畫驗證碼* 7.把內存圖像輸出到瀏覽器上*///創建內存圖像BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);//參數:寬度,高度 (指的都是像素),使用的格式(RGB)Graphics g = image.getGraphics();//畫筆就一根//設置顏色g.setColor(Color.BLUE);//畫邊框g.drawRect(0, 0, width, height);//設置顏色g.setColor(Color.GRAY);//填充矩形g.fillRect(1, 1, width-2, height-2);//設置顏色g.setColor(Color.WHITE);//拿隨機數對象Random r = new Random();//畫干擾線 10條for(int i=0;i<10;i++){g.drawLine(r.nextInt(width), r.nextInt(height),r.nextInt(width), r.nextInt(height));}//設置顏色g.setColor(Color.RED);//改變字體大小Font font = new Font("宋體", Font.BOLD,30);//參數:1字體名稱。2.字體樣式 3.字體大小g.setFont(font);//設置字體//畫驗證碼 4個int x = 35;//第一個數的橫坐標是35像素for(int i=0;i<4;i++){//r.nextInt(10)+""這種寫法效率是十分低的g.drawString(String.valueOf(r.nextInt(10)), x, 25);x+=35;}//輸出到瀏覽器上//參數: 1.內存對象。2.輸出的圖片格式。3.使用的輸出流ImageIO.write(image, "jpg", response.getOutputStream()); }public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response); }

}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-LokwoBdB-1609509272867)(assets/ResponseDemo3.png)]### 1.3.4 設置響應消息頭-控制緩存```java /*** 設置緩存時間* 使用緩存的一般都是靜態資源* 動態資源一般不能緩存。* 我們現在目前只掌握了Servlet,所以用Servlet做演示*/ public class ResponseDemo4 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {String str = "設置緩存時間";/** 設置緩存時間,其實就是設置響應消息頭:Expires 但是值是一個毫秒數。* 使用的是* response.setDateHeader();** 緩存1小時,是在當前時間的毫秒數上加上1小時之后的毫秒值*/response.setDateHeader("Expires",System.currentTimeMillis()+1*60*60*1000);response.setContentType("text/html;charset=UTF-8");response.getOutputStream().write(str.getBytes());}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-56D0vBAG-1609509272868)(assets/ResponseDemo4_chrome.png)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YRv0vxNe-1609509272869)(assets/ResponseDemo4_ie.png)]

1.3.5 設置響應消息頭定時刷新

/*** 設置響應消息頭:* 通過定時刷新演示添加消息頭*/ public class ResponseDemo5 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {String str = "用戶名和密碼不匹配,2秒后轉向登錄頁面...";response.setContentType("text/html;charset=UTF-8");PrintWriter out = response.getWriter();out.write(str);//定時刷新,其實就是設置一個響應消息頭response.setHeader("Refresh", "2;URL=/login.html");//Refresh設置的時間單位是秒,如果刷新到其他地址,需要在時間后面拼接上地址}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-aHhtMd6Z-1609509272869)(assets/ResponseDemo5.png)]

1.3.6 請求重定向:注意地址欄發生改變。

/*** 設置響應狀態碼,實現重定向* 重定向的特點:* 兩次請求,地址欄改變,瀏覽器行為,xxxx**/ public class ResponseDemo6 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//1.設置響應狀態碼 // response.setStatus(302);//2.定向到哪里去: 其實就是設置響應消息頭,Location // response.setHeader("Location", "ResponseDemo7");//使用重定向方法response.sendRedirect("ResponseDemo7");//此行做了什么事,請看上面}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}} /*** 重定向的目的地*/ public class ResponseDemo7 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.getWriter().write("welcome to ResponseDemo7");}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-L1RSlEFK-1609509272870)(assets/ResponseDemo6.png)]

1.3.7 響應和消息頭組合應用-文件下載

首先,在工程的web目錄下新建一個目錄uploads,并且拷貝一張圖片到目錄中,如下圖所示:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-myrxCkLl-1609509272871)(assets/文件下載的圖片.png)]

文件下載的Servlet代碼如下:

/*** 文件下載**/ public class ResponseDemo8 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {/** 文件下載的思路:* 1.獲取文件路徑* 2.把文件讀到字節輸入流中* 3.告知瀏覽器,以下載的方式打開(告知瀏覽器下載文件的MIME類型)* 4.使用響應對象的字節輸出流輸出到瀏覽器上*///1.獲取文件路徑(絕對路徑)ServletContext context = this.getServletContext();String filePath = context.getRealPath("/uploads/6.jpg");//通過文件的虛擬路徑,獲取文件的絕對路徑//2.通過文件路徑構建一個字節輸入流InputStream in = new FileInputStream(filePath);//3.設置響應消息頭response.setHeader("Content-Type", "application/octet-stream");//注意下載的時候,設置響應正文的MIME類型,用application/octet-streamresponse.setHeader("Content-Disposition", "attachment;filename=1.jpg");//告知瀏覽器以下載的方式打開//4.使用響應對象的字節輸出流輸出OutputStream out = response.getOutputStream();int len = 0;byte[] by = new byte[1024];while((len = in.read(by)) != -1){out.write(by, 0, len);}in.close();}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-S5Jn8P3X-1609509272871)(assets/ResponseDemo8.png)]

1.3.8 響應對象注意事項

第一: response得到的字符流和字節流互斥,只能選其一

第二:response獲取的流不用關閉,由服務器關閉即可

/*** 使用Response對象獲取流時候的注意事項:* 1.我們使用response獲取的流,可以不用關閉。服務器會給我們關閉。* 2.在response對象中,字節流和字符流互斥,輸出的時候,只能選擇一個* @author zhy**/ public class ResponseDemo9 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {String str = "test";response.getOutputStream().write(str.getBytes());//response.getWriter().write(str); // response.getOutputStream().write("haha".getBytes());}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-KA9hi0Tt-1609509272872)(assets/ResponseDemo9.png)]

2 請求對象

2.1 請求對象概述

2.1.1 關于請求

請求,顧明思議,就是使用者希望從服務器端索取一些資源,向服務器發出詢問。在B/S架構中,就是客戶瀏覽器向服務器發出詢問。在我們的JavaEE工程中,客戶瀏覽器發出詢問,要遵循HTTP協議所規定的。

請求對象,就是在JavaEE工程中,用于發送請求的對象。我們常用的對象就是ServletRequest和HttpServletRequest,它們的區別就是是否和HTTP協議有關。

2.1.2 常用請求對象

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-NeylGrvd-1609509272873)(assets/請求對象的類試圖.png)]

2.2 常用方法介紹

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-DRExlitc-1609509272873)(assets/Request方法詳解.png)]

2.3 請求對象的使用示例

2.3.1 請求對象常用方法1-獲取各種路徑

/*** 請求對象的各種信息獲取*/ public class RequestDemo1 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//本機地址:服務器地址String localAddr = request.getLocalAddr();//本機名稱:服務器名稱String localName = request.getLocalName();//本機端口:服務器端口int localPort = request.getLocalPort();//來訪者ipString remoteAddr = request.getRemoteAddr();//來訪者主機String remoteHost = request.getRemoteHost();//來訪者端口int remotePort = request.getRemotePort();//統一資源標識符String URI = request.getRequestURI();//統一資源定位符String URL = request.getRequestURL().toString();//獲取查詢字符串String queryString = request.getQueryString();//獲取Servlet映射路徑String servletPath = request.getServletPath();//輸出內容System.out.println("getLocalAddr() is :"+localAddr);System.out.println("getLocalName() is :"+localName);System.out.println("getLocalPort() is :"+localPort);System.out.println("getRemoteAddr() is :"+remoteAddr);System.out.println("getRemoteHost() is :"+remoteHost);System.out.println("getRemotePort() is :"+remotePort);System.out.println("getRequestURI() is :"+URI);System.out.println("getRequestURL() is :"+URL);System.out.println("getQueryString() is :"+queryString);System.out.println("getServletPath() is :"+servletPath);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);} }

2.3.2 請求對象常用方法2-獲取請求頭信息

/*** 獲取請求消息頭*/ public class RequestDemo2 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//1.根據名稱獲取頭的值 一個消息頭一個值String value = request.getHeader("Accept-Encoding");System.out.println("getHeader():"+value);//2.根據名稱獲取頭的值 一個頭多個值Enumeration<String> values = request.getHeaders("Accept");while(values.hasMoreElements()){System.out.println("getHeaders():"+values.nextElement());}//3.獲取請求消息頭的名稱的枚舉Enumeration<String> names = request.getHeaderNames();while(names.hasMoreElements()){String name = names.nextElement();String value1 = request.getHeader(name);System.out.println(name+":"+value1);}}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}

2.3.3 請求對象常用方法3-獲取請求參數(非常重要)

在本小節,我們會講解HttpServletRequest對象獲取請求參數的常用方法,以及把獲取到的請求參數封裝到實體類中的方式。首先,我們先來創建一個Servlet對象

/*** 封裝請求正文到javabean(數據模型)*/ public class RequestDemo3 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {/** 把下面* 1)獲取請求參數* 2)封裝請求參數到實體類中* 中定義的test1到test8逐個添加到此處來運行即可。*/}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);} }

接下來,我們在來準備一個表單頁面:

<html> <head><title>login to request demo 3</title> </head> <body> <form action="/day10_1122_requestresponse/RequestDemo3" method="post">用戶名:<input type="text" name="username" /><br/>密碼:<input type="password" name="password" /><br/>性別:<input type="radio" name="gender" value="1" checked><input type="radio" name="gender" value="0"><br/><input type="submit" value="注冊" /> </form> </body> </html>

現在,我們開始分析HttpServletRequest對象用于獲取請求參數的方法:

1)獲取請求參數

getParameter()方法的示例代碼

/*** 獲取請求正文,一個名稱對應一個值。 沒有使用確認密碼* @param request* @param response* @throws ServletException* @throws IOException*/ private void test1(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//1.獲取請求正文String username = request.getParameter("username");String password = request.getParameter("password");String gender = request.getParameter("gender");System.out.println(username+","+password+","+gender); }

getParameterValues()方法的示例代碼

/*** 獲取請求正文,一個名稱可能對應多個值 使用了確認密碼* @param request* @param response* @throws ServletException* @throws IOException */ private void test2(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//1.獲取請求正文String username = request.getParameter("username");String[] password = request.getParameterValues("password");//當表單中有多個名稱是一樣時,得到是一個字符串數組String gender = request.getParameter("gender");System.out.println(username+","+Arrays.toString(password)+","+gender); } <html> <head><title>login to request demo 4</title> </head> <body> <form action="/day10_1122_requestresponse/RequestDemo4" method="post" enctype="multipart/form-data">用戶名:<input type="text" name="username" /><br/>密碼:<input type="password" name="password" /><br/>確認密碼:<input type="password" name="password" /><br/>性別:<input type="radio" name="gender" value="1" checked><input type="radio" name="gender" value="0"><br/><input type="submit" value="注冊" /> </form> </body> </html>

getParameterNames()方法的示例代碼

/*** 獲取請求正文,一個名稱一個值。但是先要獲取正文名稱的枚舉(key的枚舉) 沒有使用確認密碼* @param request* @param response* @throws ServletException* @throws IOException */ private void test3(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//1.獲取請求正文名稱的枚舉Enumeration<String> names = request.getParameterNames();//2.遍歷正文名稱的枚舉while(names.hasMoreElements()){String name = names.nextElement();String value = request.getParameter(name);System.out.println(name+":"+value);} }

總結:

? 以上三個方法可以獲取表單提交過來的請求參數。

? 參數的名稱是一個字符串,參數的值可能是一個字符串,也可能是一個字符串數組。

2)封裝請求參數到實體類中

我們通過上面的方法可以獲取到請求參數,但是如果參數過多,在進行傳遞時,方法的形參定義將會變得非常難看。此時我們應該用一個對象來描述這些參數,它就是實體類。這種類的定義,從基礎階段我們就開始使用了。在基礎階段,我們做過一個學生管理系統,用到了一個Student的類,它就是用于描述一個學生的實體類。

我們現在要做的就是把表單中提交過來的數據填充到實體類中。

第一種:最簡單直接的封裝方式

/*** 封裝請求正文到User對象中 沒有使用確認密碼* @param request* @param response* @throws ServletException* @throws IOException*/ private void test4(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//1.獲取請求正文String username = request.getParameter("username");String password = request.getParameter("password");String gender = request.getParameter("gender");//2.創建一個User對象User user = new User();System.out.println("封裝前:"+user.toString());//3.把請求正文封裝到user對象中user.setUsername(username);user.setPassword(password);user.setGender(gender);System.out.println("封裝后:"+user.toString()); }

第二種:使用反射方式封裝

此種封裝的使用要求是,表單<input>標簽的name屬性取值,必須和實體類中定義的屬性名稱一致。

/*** 封裝請求正文到javabean中 沒有使用確認密碼* 使用反射+內省實現數據模型的封裝* 內省:是sun公司推出的一套簡化反射操作的規范。把javabean中的元素都封裝成一個屬性描述器。* 屬性描述器中會有字段信息,get和set方法(取值或存值)* @param request* @param response* @throws ServletException* @throws IOException */ private void test5(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//1.獲取請求正文名稱的枚舉Enumeration<String> names = request.getParameterNames();User user = new User();System.out.println("封裝前:"+user.toString());//2.遍歷正文名稱的枚舉while(names.hasMoreElements()){String name = names.nextElement();String value = request.getParameter(name);try{//1.拿到User對象中的屬性描述器。是誰的屬性描述器:是由構造函數的第一個參數決定的。第二個參數是指定javabean的字節碼PropertyDescriptor pd = new PropertyDescriptor(name, User.class);//參數指的就是拿哪個類的哪個屬性的描述器//2.設置javabean屬性的值Method method = pd.getWriteMethod();//3.執行方法method.invoke(user, value);//第一個參數是指的給哪個對象,第二個參數指的是賦什么值}catch(Exception e){e.printStackTrace();}}System.out.println("封裝后:"+user.toString()); }

第三種:使用反射封裝,同時請求參數的值是一個數組

此種方式其實就是針對請求參數中包含name屬性相同的參數,例如:密碼和確認密碼,還有愛好。

/*** 獲取請求正文的關系映射Map<String,String[]> 使用確認密碼* @param request* @param response* @throws ServletException* @throws IOException*/ private void test6(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//1.獲取請求正文的映射關系Map<String,String[]> map = request.getParameterMap();//2.遍歷集合for(Map.Entry<String,String[]> me : map.entrySet()){String name = me.getKey();String[] value = me.getValue();System.out.println(name+":"+Arrays.toString(value));} }

當我們把請求參數獲取出來之后,就要考慮如何針對數組的反射了,具體代碼如下:

/*** 封裝請求正文到javabean。使用的是反射+內省 使用了確認密碼* @param request* @param response* @throws ServletException* @throws IOException*/ private void test7(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//1.獲取請求正文的映射關系Map<String,String[]> map = request.getParameterMap();Users user = new Users();System.out.println("封裝前:"+user.toString());//2.遍歷集合for(Map.Entry<String,String[]> me : map.entrySet()){String name = me.getKey();String[] value = me.getValue();try{//1.拿到User對象中的屬性描述器。是誰的屬性描述器:是由構造函數的第一個參數決定的。第二個參數是指定javabean的字節碼PropertyDescriptor pd = new PropertyDescriptor(name, Users.class);//參數指的就是拿哪個類的哪個屬性的描述器//2.設置javabean屬性的值Method method = pd.getWriteMethod();//3.執行方法//判斷參數到底是幾個值if(value.length > 1){//最少有2個元素method.invoke(user, (Object)value);//第一個參數是指的給哪個對象,第二個參數指的是賦什么值}else{method.invoke(user, value);//第一個參數是指的給哪個對象,第二個參數指的是賦什么值}}catch(Exception e){e.printStackTrace();}}System.out.println("封裝后:"+user.toString()); }

當我們寫完此種封裝方式之后,同學們可以發現,我們絕大多數封裝都可以使用這段代碼來實現。并且,無論是誰來寫這段通用的封裝代碼,其代碼內容都是大同小異的。**那么,我們就可以得出一個很有趣的結論:一般遇到這種情況時,肯定有人幫我們寫好了,我們只需要用就行了。**我們后面還會遇到類似這樣的情況。

此時,幫我們寫好這段封裝代碼的是apache軟件基金會,我們前面學習的tomcat也是它提供的。它里面有一個開源工具包集合commons,里面有很多開源工具類,今天我們就來講解第一個:commons-beanutils。

第四種:使用apache的commons-beanutils實現封裝

實現代碼:

/*** 終極方法:使用beanutils實現請求正文封裝到javabean中 使用了確認密碼* 要想使用beanutils,需要先導包* @param request* @param response* @throws ServletException* @throws IOException*/ private void test8(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {Users user = new Users();System.out.println("封裝前:"+user.toString());try{BeanUtils.populate(user, request.getParameterMap());//就這一句話}catch(Exception e){e.printStackTrace();}System.out.println("封裝后:"+user.toString()); }

2.3.4 用流的形式讀取請求信息

我們除了使用2.3.3小節中獲取請求參數之外,還可以使用下面代碼中的 方式來獲取:

/*** 使用流的方式讀取請求正*/ public class RequestDemo4 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//1.獲取請求正文的字節輸入流ServletInputStream sis = request.getInputStream();//2.讀取流中的數據int len = 0;byte[] by = new byte[1024];while((len = sis.read(by)) != -1){System.out.println(new String(by,0,len));}}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}

2.3.5請求正文中中文編碼問題

關于請求中文亂碼問題,我們需要分開討論,第一是POST請求方式,第二是GET方式。

1)POST方式請求

在POST方式請求中,我們的亂碼問題可以用如下代碼解決:

/*** 請求正文的中文亂碼問題*/ public class RequestDemo5 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//1.獲取請求正文/*POST方式:* 問題:* 取的時候會不會有亂碼* 答案:* 獲取請求正文,會有亂碼問題。* 是在獲取的時候就已經亂碼了。* 解決辦法:* 是request對象的編碼出問題了* 設置request對象的字符集* request.setCharacterEncoding("GBK");它只能解決POST的請求方式,GET方式解決不了* 結論:* 請求正文的字符集和響應正文的字符集沒有關系。各是各的*/request.setCharacterEncoding("UTF-8");String username = request.getParameter("username");//輸出到控制臺System.out.println(username);//輸出到瀏覽器:注意響應的亂碼問題已經解決了response.setContentType("text/html;charset=UTF-8");PrintWriter out = response.getWriter();out.write(username);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);} }

2)GET方式請求

GET方式請求的正文是在地址欄中,在Tomcat8.5版本及以后,Tomcat服務器已經幫我們解決了,所以不會有亂碼問題了。

而如果我們使用的不是Tomcat服務器,或者Tomcat的版本是8.5以前,那么GET方式仍然會有亂碼問題,解決方式如下:(以下代碼了解即可,因為我們現在使用的是Tomcat9.0.27版本)

/*** 在Servlet的doGet方法中添加如下代碼*/ public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {/** GET方式:正文在地址欄* username=%D5%C5%C8%FD* %D5%C5%C8%FD是已經被編過一次碼了** 解決辦法:* 使用正確的碼表對已經編過碼的數據進行解碼。* 就是把取出的內容轉成一個字節數組,但是要使用正確的碼表。(ISO-8859-1)* 再使用正確的碼表進行編碼* 把字節數組再轉成一個字符串,需要使用正確的碼表,是看瀏覽器當時用的是什么碼表*/String username = request.getParameter("username");byte[] by = username.getBytes("ISO-8859-1");username = new String(by,"GBK");//輸出到瀏覽器:注意響應的亂碼問題已經解決了response.setContentType("text/html;charset=UTF-8");PrintWriter out = response.getWriter();out.write(username); }public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response); }

2.3.6 請求轉發(與重定向的區別)

在實際開發中,重定向和請求轉發都是我們要用到的響應方式,那么他們有什么區別呢?我們通過下面的示例來看一下:

/*** 重定向特點:* 兩次請求,瀏覽器行為,地址欄改變,請求域中的數據會丟失* 請求轉發:* 一次請求,服務器行為,地址欄不變,請求域中的數據不丟失** 請求域的作用范圍:* 當前請求(一次請求),和當前請求的轉發之中*/ public class RequestDemo6 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//1.拿到請求調度對象RequestDispatcher rd = request.getRequestDispatcher("/RequestDemo7");//如果是給瀏覽器看的,/可寫可不寫。如果是給服務器看的,一般情況下,/都是必須的。//放入數據到請求域中request.setAttribute("CityCode", "bj-010");//2.實現真正的轉發操作rd.forward(request, response);//實現真正的轉發操作}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}public class RequestDemo7 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//獲取請求域中的數據String value = (String)request.getAttribute("CityCode");response.getWriter().write("welcome to request demo 7 "+value);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}

2.3.7 請求包含

在實際開發中,我們可能需要把兩個Servlet的內容合并到一起來響應瀏覽器,而同學們都知道HTTP協議的特點是一請求,一響應的方式。所以絕對不可能出現有兩個Servlet同時響應方式。那么我們就需要用到請求包含,把兩個Servlet的響應內容合并輸出。我們看具體使用示例:

/*** 請求包含** 它是把兩個Servlet的響應內容合并輸出。* 注意:* 這種包含是動態包含。** 動態包含的特點:* 各編譯各的,只是最后合并輸出。*/ public class RequestDemo8 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.getWriter().write("I am request demo8 ");//1.拿到請求調度對象RequestDispatcher rd = request.getRequestDispatcher("/RequestDemo9");//2.實現包含的操作rd.include(request, response);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);} }public class RequestDemo9 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.getWriter().write("include request demo 9 ");}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}

2.3.8 細節問題

請求轉發的注意事項:負責轉發的Servlet,轉發前后的響應正文丟失,由轉發目的地來響應瀏覽器。

請求包含的注意事項:被包含者的響應消息頭丟失。因為它被包含起來了。

總結

以上是生活随笔為你收集整理的RequestResponse的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 五月天欧美 | 久久久高清 | aa片在线观看视频在线播放 | 久久97精品久久久久久久不卡 | 中文字幕日韩有码 | 芒果视频污污 | 夜夜嗷| 美女又黄又免费 | 一区二区三区视频免费视 | 国产又大又粗又硬 | 91麻豆视频网站 | 国产欧美激情在线观看 | 亚洲AV午夜成人片 | 国产又黄又爽视频 | av片免费看| 嫩草在线播放 | 五月激情婷婷在线 | 成人免费在线播放 | 久久亚洲AV成人无码一二三 | 又黄又爽一区二区三区 | 日韩亚洲一区二区三区 | www.天堂av | 国产人妖在线播放 | 国产农村乱对白刺激视频 | 国产视频一区二区三 | 欧美xxxx18国产 | 91高清视频免费观看 | 国产成人日韩 | 成人福利网站在线观看 | 亚洲丝袜中文字幕 | 人体裸体bbb欣赏 | 欧美五月激情 | 免费网站在线高清观看 | 99青草| 亚洲一级片av | 青草福利| 国模私拍av | 青青操免费 | 亚洲人一区二区三区 | 污污污www精品国产网站 | 黄色网址哪里有 | 国产一区二区三区在线观看视频 | 人人超碰人人 | 亚洲成人精品在线观看 | 老色批网站 | 色8久久| 福利视频在线导航 | 欧美专区综合 | 黄色a视频| 国产真实乱 | 欧美激情在线免费 | 草久久免费视频 | 久久国产精品精品国产色婷婷 | 黄色三级带 | 51av视频 | 玖玖在线免费视频 | 1000部国产精品成人观看 | 亚洲成人黄色影院 | 免费一级片网站 | 性色av一区二区三区四区 | 一本色道久久综合熟妇 | 99国产揄拍国产精品 | wwwxxx日本免费 | 国产精品偷乱一区二区三区 | 国产精品夜夜躁视频 | 国产欧美日韩综合 | 成人四色 | 最近2018年手机中文字幕版 | 中国丰满人妻videoshd | 精品久久电影 | 男女视频在线观看 | 国产精品s色 | 91制服诱惑 | 又黄又爽又色视频 | 永久免费在线看片 | 激情四射婷婷 | 国产精品视频一区在线观看 | 韩国无码av片在线观看网站 | 欧美激情在线一区 | 欧美色视频在线 | chinese精品自拍hd| 日韩激情视频在线 | 青娱乐在线视频免费观看 | av性天堂网 | 超碰人操 | 总裁边开会边做小娇妻h | 在线久草| 日日爱av | av黄色免费| 欧美亚色| 久久综合免费视频 | 亚洲天堂一级片 | 激情婷婷丁香 | 在线观看一二三区 | 99视频在线看 | 成人免费网站在线观看 | 新婚若妻侵犯中文字幕 | 一区二区三区小视频 | 日韩免费视频一区二区 |