Jadvaweb客戶端與服務端的通信-Request請求與Response響應

Jadvaweb客戶端與服務端的通信-Request請求與Response響應

相對路徑與絕對路徑

相對路徑訪問servlet

xml映射配置:

<servlet-mapping>
    <servlet-name>HelloWorld</servlet-name>
    <url-pattern>/HELLO</url-pattern>
</servlet-mapping>

Servlet映射爲/HELLO,代表根目錄下的HELLO

此時在IDEA的web/下(根目錄)新建html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<br>
<a href="./HELLO">點擊訪問Servlet</a>
  <!--  <a href="./HELLO">點擊訪問Servlet</a> 等效-->
</body>
</html>

超鏈接設置爲 ./HELLO 代表上一級目錄下的HELLO 同理,…/代表退兩層

啓動Tomcat,訪問http://localhost:8081/can.html

點擊超鏈接

成功訪問

絕對路徑訪問Servlet

方式一:

直接跟瀏覽器地址欄對應,沒什麼好說的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a href="http://localhost:8081/HELLO">點擊訪問Servlet</a>
</body>
</html>

缺點:

ip與端口寫死了,一旦ip與端口改動,超鏈接失效,該方式不建議使用

Tomcat請求響應

Web服務器收到客戶端的http請求,會針對每一次請求,分別創建一個用於代表請求的request對象、和代表響應的response對象request和response對象即然代表請求和響應,那我們要獲取客戶機提交過來的數據,只需要找request對象就行了。要向客戶機輸出數據,只需要找response對象就行了

HttpServletRequest基本功能

ttpServletRequest在JavaWeb中非常重要的一個類。它是Servlet的service()方法的參數之一!所以你必須必須要掌握它!

request的功能可以分爲以下幾種:

  • 封裝了請求頭數據

  • 封裝了請求正文數據,如果是GET請求,那麼就沒有正文

  • request是一個域對象,可以把它當成Map來添加獲取數據

  • 做請求的轉發

獲取請求頭數據:

String value = request.getHeader("請求頭名稱")

quest對象可以用來獲取請求頭數據,當然,這些請求數據都是Tomcat封裝到request中去的。我們在service()方法中可以直接來獲取相關的方法

其他:

equest中還提供了與請求相關的其他方法,有些方法是爲了我們更加便捷的方法請求頭數據而設計,有些是與請求URL相關的方法

  • int getContentLength():獲取請求正文的字節數,GET請求沒有正文,沒有正文返回-1

  • String getContentType():獲取請求類型,如果請求是GET,那麼這個方法返回null;如果是POST請求,那麼默認爲application/x-www-form-urlencoded(理解爲字符串類型),其它類型以後再學;

  • String getMethod():返回請求方法,例如:GET

  • Locale getLocale():返回當前客戶端瀏覽器支持的Locale。java.util.Locale表示國家和言語,這個東西在國際化中很有用

  • String getCharacterEncoding():獲取請求編碼,如果沒有setCharacterEncoding(),那麼返回null。表示使用ISO-8859-1編碼

  • void setCharacterEncoding(String code):設置請求編碼,只對正文有效!注意,對於GET而言,沒有正文!!!所以此方法只能對POST請求中的參數有效

  • String getContextPath():返回項目路徑,例如:/項目名稱

  • String getQueryString():返回請求URL中的參數,例如:name=zhangSan

  • String getRequestURI():返回要請求URI路徑,例如:/hello/oneServlet

  • String getServletPath():返回Servlet路徑,例如:/oneServlet

  • String getSchema():返回請求協議,例如:http

  • String getServerName():返回主機名,例如:localhost

  • int getServerPort():返回服務器端口號,例如:80

  • int getRemotePort():返回客戶端的端口號,每次請求都會變

HttpServletRequest參數

獲取參數

可以使用HttpServletRequest獲取客戶端的請求參數,相關方法如下:

String getParameter(String name):通過指定名稱獲取參數值;

String[] getParameterValues(String name):通過指定名稱獲取參數值數組,有可能一個名字對應多個值,例如表單中的多個複選框使用相同的name時;

Enumeration getParameterNames():獲取所有參數的名字;

Map getParameterMap():獲取所有參數對應的Map,其中key爲參數名,value爲參數值。

傳遞參數

GET:

地址欄中直接給出參數:http://localhost/param/ParamServlet?p1=v1&p2=v2;

超鏈接中給出參數:<a href=” http://localhost/param/ParamServlet?p1=v1&p2=v2”>???</a>

表單中給出參數:<form method="GET" action="ParamServlet">…</form>

Ajax暫不介紹

POST:

表單中給出參數:<form method="POST" action="ParamServlet">…</form>

Ajax暫不介紹

接收參數

單值參數接收:

單值參數包括單選,單值下拉框,文本,隱藏域

無論是GET還是POST,獲取參數的方法是相同的

String s1 = request.getParameter(“p1”);//返回v1

圖示:

多值參數接收:

多值參數主要就是多選checkbox

例如在註冊表單中,如果讓用戶填寫愛好,那麼愛好可能就是多個,那麼hobby參數就會對應多個值:

request.getParameterMap()方法返回Map類型,對應所有參數,其中Map的key對應參數的名字;Map的value對應參數的值

示例:

<form action="ParamServlet" method="post">
		姓名:<input type="text" name="name"/><br/>
		年齡:<input type="text" name="age"/><br/>
		性別:<input type="text" name="sex"/><br/>
    	<input type="submit" value="提交"/><br/>
    </form>
		Map<String,String[]> map = request.getParameterMap();
		Set<String> keys = map.keySet();//獲得所有鍵
		for(String key : keys) {
			String[] value = map.get(key);//由鍵拿值
			System.out.println(key + " = " + value[0]);
		}
sex = male
name = zhangSan
age = 23

圖解:

其實當參數的值是單個的時候,同樣可以使用request.getParameterValues(String)方法來獲取參數值,不過這個參數返回的值爲String[],這時我們需要再去獲取數組下標0的元素

String name = request.getParameterValues(“name”)[0];

Request請求中文亂碼問題

我們在做項目時會全站都採用統一的編碼,最常用的就是UTF-8,也就是說request請求所帶的參數是utf-8編碼的

Post亂碼問題

我們知道,請求信息中,只有POST存在正文,所謂POST參數編碼就是就是請求正文的編碼。

默認情況下,使用getParameter()獲取POST請求參數時,使用的是ISO-8859-1編碼,而我們請求是統一設置稱UTF-8的,故在獲取參數時已經被錯誤的編碼了

解決辦法一:

先使用ISO-8859-1獲取字節數組,然後再使用正確的UTF-8編碼得到字符串,這樣就沒問題了

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getOutputStream().write(" doPost方法被調用".getBytes());
        String name = req.getParameter("name");
        name = new String(name.getBytes("ISO-8859-1"), "UTF-8");
        System.out.println(name);
    }

解決方法二:

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getOutputStream().write(" doPost方法被調用".getBytes());
        req.setCharacterEncoding("UTF-8");
        String name = req.getParameter("name");

        System.out.println(name);
    }

request的setCharacterEncodng()可以設置編碼,當然這必須在調用所有的getParameter()方法之前調用request的setCharacterEncodng()方法來設置編碼,這樣,就不會使用ISO解讀字節串了,而是使用你給定的編碼來解讀。

對於每個請求,只需要調用request的setCharacterEncodng()一次,然後所有getParameter()都會使用這個編碼來解讀參數。但要注意,只對請求正文有效,即POST參數。

Get亂碼問題

第一種方式:

採用字符串轉碼的方式來處理

	String s = request.getParameter(“s”);

	s = new String(s.getBytes(“iso-8859-1), “utf-8);

第二種方式:

設置< Connector>元素的URIEncoding屬性的值爲UTF-8。即conf\server.xml中的< Connector>元素的URIEncoding屬性

一旦設置了這個屬性,那麼對於GET參數就直接是UTF-8編碼的了。但是,< Connector>元素來說,對整個Tomcat都是有效的

注意:GET參數不在請求正文中,而是在URL中。所以不能使用request的setCharacterEncodng()來設置GET參數的編碼

第三種方式:

依賴於JS,是把GET請求中的參數使用JavaScript做URL編碼,URL編碼後的內容就不再是中文了,這樣也就不會丟失字節(亂碼)了

<a href="#" onclick="click1()">ff</a>
<script type="text/javascript">
function click1(){
	var path = encodeURI(encodeURI("/servlet?namea=悟空"));
	location.href = path;
}
</script>
String val = request.getParameter("namea");
		val = URLDecoder.decode(val, "UTF-8");
		System.out.println(val);

HttpServletRequest請求轉發

在Servlet中請求轉發是大量要使用的,因爲當我們訪問一個Servlet的時候通常會執行一些後臺的業務邏輯,然後跳轉到一個結果頁面,那麼跳轉到結果頁面的這個過程就是請求轉發,舉個例子我們做登錄的功能,我們填寫用戶名密碼然後提交到一個負責登錄的Servlet,Servlet爲我們做用戶名和密碼的校驗,如果我們都正確的話,我們就要跳轉到登錄的提示頁面,如果錯誤就要跳轉到登錄失敗的頁面

Request的請求轉發也可以叫做服務器端的跳轉,雖然有頁面的跳轉但是我們會發現地址欄是不會有變化的

示例代碼:

request.getRequestDispatcher("/success.html").forward(request, response);

Request域的作用範圍

ServletContext是一個域的對象,它的範圍非常大,是指定項目所有Servlet的公共的對象,隨着服務器的啓動而產生,服務器的停止而銷燬,那麼request的也是域對象,它的作用範圍小的多,它的範圍只在一次請求響應範圍之內,每一個線程的請求都會新產生一個HttpServletRequest和HttpServletResponse的對象

HttpServletResponse基本功能

response對象的功能分爲以下四種:

設置響應頭信息;addHeader(“reFresh”, “5;URL=xxxx”);

發送狀態碼;sendError(404);

設置響應正文;getWriter().print(“aaa”);

重定向:sendRedirect(“path”);

其他方法:

  • response.setContentType("text/html;charset=utf-8"):設置響應類型爲html,編碼爲utf-8,處理相應頁面文本顯示的亂碼

  • response.setCharacterEncoding(“utf-8”):如果響應類型爲文本,那麼就需要設置文本的編碼類型,然後瀏覽器使用這個編碼來解讀文本。注意,如果沒有設置contentType,那麼瀏覽器會認爲contentType爲text/html,如果沒設置編碼,那麼默認爲ISO-8859-1編碼。所以以上兩點在使用response返回結果之前必須設置

  • response.setHeader(“contentType”, “text/html;charset=utf-8”):setContentType()方法的功能相同。setContentType()方法屬於便捷方法

  • response.setHeader("Refresh","5; URL=http://www.baidu.com"):5秒後自動跳轉到百度主頁

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章