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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Servlet第四篇【request对象常用方法、应用】

發布時間:2025/3/12 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Servlet第四篇【request对象常用方法、应用】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是HttpServletRequest

HttpServletRequest對象代表客戶端的請求,當客戶端通過HTTP協議訪問服務器時,HTTP請求頭中的所有信息都封裝在這個對象中,開發人員通過這個對象的方法,可以獲得客戶這些信息。

簡單來說,要得到瀏覽器信息,就找HttpServletRequest對象

HttpServletRequest常用方法

獲得客戶機【瀏覽器】信息

  • getRequestURL方法返回客戶端發出請求時的完整URL。
  • getRequestURI方法返回請求行中的資源名部分。
  • getQueryString 方法返回請求行中的參數部分。
  • getPathInfo方法返回請求URL中的額外路徑信息。額外路徑信息是請求URL中的位于Servlet的路徑之后和查詢參- 數之前的內容,它以“/”開頭。
  • getRemoteAddr方法返回發出請求的客戶機的IP地址
  • getRemoteHost方法返回發出請求的客戶機的完整主機名
  • getRemotePort方法返回客戶機所使用的網絡端口號
  • getLocalAddr方法返回WEB服務器的IP地址。
  • getLocalName方法返回WEB服務器的主機名

獲得客戶機請求頭

  • getHeader方法
  • getHeaders方法
  • getHeaderNames方法

獲得客戶機請求參數(客戶端提交的數據)

  • getParameter方法
  • getParameterValues(String name)方法
  • getParameterNames方法
  • getParameterMap方法

HttpServletRequest應用

防盜鏈

什么是防盜鏈呢?比如:我現在有海賊王最新的資源,想要看海賊王的要在我的網頁上看。現在別的網站的人看到我有海賊王的資源,想要把我的資源粘貼在他自己的網站上。這樣我獨家的資源就被一個CTRL+C和CTRL+V搶走了?而反盜鏈就是不能被他們CRTL+C和CRTL+V

下面我模擬一下場景。現在我首頁先有一個超鏈接,指向著海賊王最新資源

當我點進去,就能看到海賊王最新資源了

其他的人可以通過復制粘貼我的地址,放到它們的網頁上

這樣我就劃不來啦【我的廣告你來沒看呢!】。想要看我的資源,就必須經過我的首頁點進去看。

想要實現這樣的效果,就要獲取Referer這個消息頭,判斷Referer是不是從我的首頁來的。如果不是從我的首頁來的,跳轉回我的首頁。

//獲取到網頁是從哪里來的String referer = request.getHeader("Referer");//如果不是從我的首頁來或者從地址欄直接訪問的,if ( referer == null || !referer.contains("localhost:8080/zhongfucheng/index.jsp") ) {//回到首頁去response.sendRedirect("/zhongfucheng/index.jsp");return;}//能執行下面的語句,說明是從我的首頁點擊進來的,那沒問題,照常顯示response.setContentType("text/html;charset=UTF-8");response.getWriter().write("路飛做了XXXXxxxxxxxxxxxxxxxx");

首先按正常預想的,別人從首頁點擊我的資源,訪問我海賊王最新的資源

能夠成功訪問到資源

如果我在瀏覽器直接輸入地址【此時Referer是為null的】,我們來看看

跳回到首頁上,不能訪問到海賊王資源

再試試,如果別人粘貼了我的資源url,在它的網頁上掛了一個網址呢。

在別人網頁上點擊的時候

又跳回到了我的首頁了。

表單提交數據【通過post方式提交數據】

<form action="/zhongfucheng/Servlet111" method="post"><table><tr><td>用戶名</td><td><input type="text" name="username"></td></tr><tr><td>密碼</td><td><input type="password" name="password"></td></tr><tr><td>性別</td><td><input type="radio" name="gender" value="男"><input type="radio" name="gender" value="女"></td></tr><tr><td>愛好</td><td><input type="checkbox" name="hobbies" value="游泳">游泳<input type="checkbox" name="hobbies" value="跑步">跑步<input type="checkbox" name="hobbies" value="飛翔">飛翔</td></tr><input type="hidden" name="aaa" value="my name is zhongfucheng"><tr><td>你的來自于哪里</td><td><select name="address"><option value="廣州">廣州</option><option value="深圳">深圳</option><option value="北京">北京</option></select></td></tr><tr><td>詳細說明:</td><td><textarea cols="30" rows="2" name="textarea"></textarea></td></tr><tr><td><input type="submit" value="提交"></td><td><input type="reset" value="重置"></td></tr></table>

在Servlet111中獲取到提交的數據,代碼如下

//設置request字符編碼的格式request.setCharacterEncoding("UTF-8");//通過html的name屬性,獲取到值String username = request.getParameter("username");String password = request.getParameter("password");String gender = request.getParameter("gender");//復選框和下拉框有多個值,獲取到多個值String[] hobbies = request.getParameterValues("hobbies");String[] address = request.getParameterValues("address");//獲取到文本域的值String description = request.getParameter("textarea");//得到隱藏域的值String hiddenValue = request.getParameter("aaa");....各種System.out.println().......

向表單輸入數據

Servlet111得到表單帶過來的數據,最后的一個數據是隱藏域帶過來的。

超鏈接方式提交數據

常見的get方式提交數據有:使用超鏈接,sendRedirect()

格式如下:

sendRedirect("servlet的地址?參數名="+參數值 &"參數名="+參數值);

我們來使用一下,通過超鏈接將數據帶給瀏覽器

<a href="/zhongfucheng/Servlet111?username=xxx">使用超鏈接將數據帶給瀏覽器</a>

在Servlet111接收數據

//接收以username為參數名帶過來的值String username = request.getParameter("username");System.out.println(username);

注意看瀏覽器左下角

服務器成功接收到瀏覽器發送過來的數據

并且,傳輸數據明文的出現在瀏覽器的地址欄上

sendRedirect()和超鏈接類似,在這里就不贅述了

解決中文亂碼問題

細心的朋友會發現,我在獲取表單數據的時候,有這句代碼request.setCharacterEncoding(“UTF-8”);,如果沒有這句代碼,會發生什么事呢?我們看看。

再重新填寫數據

在服務器查看提交過來的數據,所有的中文數據都亂碼了

來這里我們來分析一下亂碼的原因,在前面的博客中我已經介紹了,Tomcat服務器默認編碼是ISO 8859-1,而瀏覽器使用的是UTF-8編碼。瀏覽器的中文數據提交給服務器,Tomcat以ISO 8859-1編碼對中文編碼,當我在Servlet讀取數據的時候,拿到的當然是亂碼。而我設置request的編碼為UTF-8,亂碼就解決了。

接下來使用get方式傳遞中文數據,把表單的方式改成get即可

當我們訪問的時候,又出現亂碼了!


于是我按照上面的方式,把request對象設置編碼為UTF-8試試

request.setCharacterEncoding("UTF-8");String name = request.getParameter("name");

結果還是亂碼。這是為什么呢?我明明已經把編碼設置成UTF-8了,按照post方式,亂碼問題已經解決了!。我們來看看get和post方式的區別在哪?為什么post方式設置了request編碼就可以解決亂碼問題,而get方式不能呢。

首先我們來看一下post方法是怎么進行參數傳遞的。當我們點擊提交按鈕的時候,數據封裝進了Form Data中,http請求中把實體主體帶過去了【傳輸的數據稱之為實體主體】,既然request對象封裝了http請求,所以request對象可以解析到發送過來的數據,于是只要把編碼設置成UTF-8就可以解決亂碼問題了。

而get方式不同,它的數據是從消息行帶過去的,沒有封裝到request對象里面,所以使用request設置編碼是無效的。

要解決get方式亂碼問題也不難,我們既然知道Tomcat默認的編碼是ISO 8859-1,那么get方式由消息體帶過去給瀏覽器的時候肯定是用ISO 8859-1編碼了。

//此時得到的數據已經是被ISO 8859-1編碼后的字符串了,這個是亂碼String name = request.getParameter("username");//亂碼通過反向查ISO 8859-1得到原始的數據byte[] bytes = name.getBytes("ISO8859-1");//通過原始的數據,設置正確的碼表,構建字符串String value = new String(bytes, "UTF-8");

上面的代碼有些難理解,我畫張圖說明一下:

經過我們手工轉換,再來訪問一下

好的,成功解決掉亂碼問題了。

除了手工轉換,get方式還可以改Tomcat服務器的配置來解決亂碼,但是不推薦使用,這樣不靈活。“

我們都知道Tomcat默認的編碼是ISO 8859-1,如果在Tomcat服務器的配置下改成是UTF-8的編碼,那么就解決服務器在解析數據的時候造成亂碼問題了

在8080端口的Connector上加入URIEncoding=“utf-8”,設置Tomcat的訪問該端口時的編碼為utf-8,從而解決亂碼,這種改法是固定使用UTF-8編碼的

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="utf-8"/>

設置了編碼后,沒有做任何手工轉換,成功拿到數據


當然也有另一種改服務器編碼的方式。設置Tomcat的訪問該端口時的編碼為頁面的編碼,這種改法是隨著頁面的編碼而變

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" useBodyEncodingForURI="true" />

設置編碼為UTF-8

request.setCharacterEncoding("UTF-8");String name = request.getParameter("name");

再次訪問

手寫超鏈接如果附帶中文參數問題,要URL重寫,在JSP博客中會講到

總結

  • post方式直接改request對象的編碼
  • get方式需要手工轉換編碼
  • get方式也可以修改Tomcat服務器的編碼,不推薦,因為會太依賴服務器了!
  • 提交數據能用post就用post

實現轉發

之前講過使用response的sendRedirect()可以實現重定向,做到的功能是頁面跳轉,使用request的getRequestDispatcher.forward(request,response)實現轉發,做到的功能也是頁面跳轉,他們有什么區別呢?現在我先來說下轉發

代碼如下所示

//獲取到requestDispatcher對象,跳轉到index.jspRequestDispatcher requestDispatcher = request.getRequestDispatcher("/index.jsp");//調用requestDispatcher對象的forward()實現轉發,傳入request和response方法requestDispatcher.forward(request, response);

訪問Servlet111

上面已經說了,可以通過sendRedirect()重定向可以在資源尾部添加參數提交數據給服務器。那么轉發能不能提交數據給服務器呢?

答案明顯是可以的,并且使用這種方法非常頻繁

在講ServletContext的時候,曾經說過Servlet之間可以通過ServletContext實現通訊,ServletContext也能稱之為域對象。而request也可以稱之為域對象,只不過ServletContext的域是整個web應用,而request的域僅僅代表一次http請求

下面我們來使用request實現Servlet之間的通訊,Servlet111代碼

//以username為關鍵字存zhongfucheng值request.setAttribute("username", "zhongfucheng");//獲取到requestDispatcher對象RequestDispatcher requestDispatcher = request.getRequestDispatcher("/Servlet222");//調用requestDispatcher對象的forward()實現轉發,傳入request和response方法requestDispatcher.forward(request, response);

Servlet222代碼

//獲取到存進request對象的值String userName = (String) request.getAttribute("username");//在瀏覽器輸出該值response.getWriter().write("i am :"+userName);

訪問Servlet111看下效果

如上圖所示,Servlet222成功拿到了request對象在Servlet111存進的數據。

現在問題又來了,我們可以使用ServletContext和request實現Servlet之間的通訊,那么我們用哪一種呢?一般的原則:可以使用request就盡可能使用request。因為ServletContext代表著整個web應用,使用ServletContext會消耗大量的資源,而request對象會隨著請求的結束而結束,資源會被回收。使用request域進行Servlet之間的通訊在開發中是非常頻繁的。

轉發的時序圖

請求轉發的細節

如果在調用forward方法之前,在Servlet程序中寫入的部分內容已經被真正地傳送到了客戶端,forward方法將拋出IllegalStateException異常。 也就是說:不要在轉發之前寫數據給瀏覽器

我們來試試是不是真的會出現異常。

OutputStream outputStream = response.getOutputStream();outputStream.write("--------------------------------------------".getBytes());//關閉流,確保讓數據到瀏覽器中outputStream.close();//跳轉request.getRequestDispatcher("/Foot").forward(request, response);

訪問的時候,看到瀏覽器可以輸出數據,Tomcat后臺拋出了異常


如果在調用forward方法之前向Servlet引擎的緩沖區中寫入了內容,只要寫入到緩沖區中的內容還沒有被真正輸出到客戶端,forward方法就可以被正常執行,原來寫入到輸出緩沖區中的內容將被清空,但是,已寫入到HttpServletResponse對象中的響應頭字段信息保持有效。

轉發和重定向的區別

實際發生位置不同,地址欄不同

轉發是發生在服務器的

  • 轉發是由服務器進行跳轉的,細心的朋友會發現,在轉發的時候,瀏覽器的地址欄是沒有發生變化的,在我訪問Servlet111的時候,即使跳轉到了Servlet222的頁面,瀏覽器的地址還是Servlet111的。也就是說瀏覽器是不知道該跳轉的動作,轉發是對瀏覽器透明的。通過上面的轉發時序圖我們也可以發現,實現轉發只是一次的http請求,一次轉發中request和response對象都是同一個。這也解釋了,為什么可以使用request作為域對象進行Servlet之間的通訊。

重定向是發生在瀏覽器的

  • 重定向是由瀏覽器進行跳轉的,進行重定向跳轉的時候,瀏覽器的地址會發生變化的。曾經介紹過:實現重定向的原理是由response的狀態碼和Location頭組合而實現的。這是由瀏覽器進行的頁面跳轉實現重定向會發出兩個http請求,request域對象是無效的,因為它不是同一個request對象

用法不同

很多人都搞不清楚轉發和重定向的時候,資源地址究竟怎么寫。有的時候要把應用名寫上,有的時候不用把應用名寫上。很容易把人搞暈。記住一個原則:給服務器用的直接從資源名開始寫,給瀏覽器用的要把應用名寫上

  • request.getRequestDispatcher("/資源名 URI").forward(request,response)
    轉發時"/"代表的是本應用程序的根目錄【zhongfucheng】
  • response.send("/web應用/資源名 URI");
    重定向時"/"代表的是webapps目錄

能夠去往的URL的范圍不一樣

  • 轉發是服務器跳轉只能去往當前web應用的資源
  • 重定向是瀏覽器跳轉,可以去往任何的資源

傳遞數據的類型不同

  • 轉發的request對象可以傳遞各種類型的數據,包括對象
  • 重定向只能傳遞字符串

跳轉的時間不同

  • 轉發時:執行到跳轉語句時就會立刻跳轉
  • 重定向:整個頁面執行完之后才執行跳轉

轉發和重定向使用哪一個?

根據上面說明了轉發和重定向的區別也可以很容易概括出來。轉發是帶著轉發前的請求的參數的。重定向是新的請求。

典型的應用場景:

  • 轉發: 訪問 Servlet 處理業務邏輯,然后 forward 到 jsp 顯示處理結果,瀏覽器里 URL 不變
  • 重定向: 提交表單,處理成功后 redirect 到另一個 jsp,防止表單重復提交,瀏覽器里 URL 變了
  • RequestDispatcher再說明

    RequestDispatcher對象調用forward()可以實現轉發上面已經說過了。RequestDispatcher還有另外一個方法include(),該方法可以實現包含,有什么用呢?

    我們在寫網頁的時候,一般網頁的頭部和尾部是不需要改變的。如果我們多個地方使用Servlet輸出網頭和網尾的話,需要把代碼重新寫一遍。而使用RequestDispatcher的include()方法就可以實現包含網頭和網尾的效果了。

    我們來操作吧!現在我有網頭和網尾的Servlet

    使用Servlet111將網頭和網尾包含

    request.getRequestDispatcher("/Head").include(request, response);response.getWriter().write("--------------------------------------------");request.getRequestDispatcher("/Foot").include(request, response);

    訪問一下Servlet111,成功把網頭和網尾包含了

    總結

    以上是生活随笔為你收集整理的Servlet第四篇【request对象常用方法、应用】的全部內容,希望文章能夠幫你解決所遇到的問題。

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