一姐叁、HttpServletRequest介紹
HttpServletRequest對象代表客戶端的請求,當(dāng)客戶端通過HTTP協(xié)議訪問服務(wù)器時(shí)偷俭,HTTP請求頭中的所有信息都封裝在這個(gè)對象中踩麦,通過這個(gè)對象提供的方法虹曙,可以獲得客戶端請求的所有信息。
二绒障、Request常用方法
2.1吨凑、獲得客戶機(jī)信息
getRequestURL方法返回客戶端發(fā)出請求時(shí)的完整URL。
getRequestURI方法返回請求行中的資源名部分。
getQueryString 方法返回請求行中的參數(shù)部分鸵钝。
getPathInfo方法返回請求URL中的額外路徑信息糙臼。額外路徑信息是請求URL中的位于Servlet的路徑之后和查詢參數(shù)之前的內(nèi)容,它以“/”開頭恩商。
getRemoteAddr方法返回發(fā)出請求的客戶機(jī)的IP地址变逃。
getRemoteHost方法返回發(fā)出請求的客戶機(jī)的完整主機(jī)名。
getRemotePort方法返回客戶機(jī)所使用的網(wǎng)絡(luò)端口號怠堪。
getLocalAddr方法返回WEB服務(wù)器的IP地址揽乱。
getLocalName方法返回WEB服務(wù)器的主機(jī)名。
范例:通過request對象獲取客戶端請求信息
package gacl.request.study;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author gacl
* 通過request對象獲取客戶端請求信息
*/
public class RequestDemo01 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/**
* 1.獲得客戶機(jī)信息
*/
String requestUrl = request.getRequestURL().toString();//得到請求的URL地址
String requestUri = request.getRequestURI();//得到請求的資源
String queryString = request.getQueryString();//得到請求的URL地址中附帶的參數(shù)
String remoteAddr = request.getRemoteAddr();//得到來訪者的IP地址
String remoteHost = request.getRemoteHost();
int remotePort = request.getRemotePort();
String remoteUser = request.getRemoteUser();
String method = request.getMethod();//得到請求URL地址時(shí)使用的方法
String pathInfo = request.getPathInfo();
String localAddr = request.getLocalAddr();//獲取WEB服務(wù)器的IP地址
String localName = request.getLocalName();//獲取WEB服務(wù)器的主機(jī)名
response.setCharacterEncoding("UTF-8");//設(shè)置將字符以"UTF-8"編碼輸出到客戶端瀏覽器
//通過設(shè)置響應(yīng)頭控制瀏覽器以UTF-8的編碼顯示數(shù)據(jù)研叫,如果不加這句話锤窑,那么瀏覽器顯示的將是亂碼
response.setHeader("content-type", "text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write("獲取到的客戶機(jī)信息如下:");
out.write("<hr/>");
out.write("請求的URL地址:"+requestUrl);
out.write("<br/>");
out.write("請求的資源:"+requestUri);
out.write("<br/>");
out.write("請求的URL地址中附帶的參數(shù):"+queryString);
out.write("<br/>");
out.write("來訪者的IP地址:"+remoteAddr);
out.write("<br/>");
out.write("來訪者的主機(jī)名:"+remoteHost);
out.write("<br/>");
out.write("使用的端口號:"+remotePort);
out.write("<br/>");
out.write("remoteUser:"+remoteUser);
out.write("<br/>");
out.write("請求使用的方法:"+method);
out.write("<br/>");
out.write("pathInfo:"+pathInfo);
out.write("<br/>");
out.write("localAddr:"+localAddr);
out.write("<br/>");
out.write("localName:"+localName);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
運(yùn)行結(jié)果:
2.2、獲得客戶機(jī)請求頭
getHeader(string name)方法:String
getHeaders(String name)方法:Enumeration
getHeaderNames()方法
范例:通過request對象獲取客戶端請求頭信息
package gacl.request.study;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author gacl
* 獲取客戶端請求頭信息
* 客戶端請求頭:
*
*/
public class RequestDemo02 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");//設(shè)置將字符以"UTF-8"編碼輸出到客戶端瀏覽器
//通過設(shè)置響應(yīng)頭控制瀏覽器以UTF-8的編碼顯示數(shù)據(jù)
response.setHeader("content-type", "text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
Enumeration<String> reqHeadInfos = request.getHeaderNames();//獲取所有的請求頭
out.write("獲取到的客戶端所有的請求頭信息如下:");
out.write("<hr/>");
while (reqHeadInfos.hasMoreElements()) {
String headName = (String) reqHeadInfos.nextElement();
String headValue = request.getHeader(headName);//根據(jù)請求頭的名字獲取對應(yīng)的請求頭的值
out.write(headName+":"+headValue);
out.write("<br/>");
}
out.write("<br/>");
out.write("獲取到的客戶端Accept-Encoding請求頭的值:");
out.write("<hr/>");
String value = request.getHeader("Accept-Encoding");//獲取Accept-Encoding請求頭對應(yīng)的值
out.write(value);
Enumeration<String> e = request.getHeaders("Accept-Encoding");
while (e.hasMoreElements()) {
String string = (String) e.nextElement();
System.out.println(string);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
運(yùn)行結(jié)果如下:
2.3嚷炉、獲得客戶機(jī)請求參數(shù)(客戶端提交的數(shù)據(jù))
-
getParameter(String)方法
(常用)
-
getParameterValues(String name)方法
(常用)
getParameterNames()方法(不常用)
-
getParameterMap()方法
(編寫框架時(shí)常用)
比如現(xiàn)在有如下的form表單
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Html的Form表單元素</title>
</head>
<fieldset style="width:500px;">
<legend>Html的Form表單元素</legend>
<!--form表單的action屬性規(guī)定當(dāng)提交表單時(shí)渊啰,向何處發(fā)送表單數(shù)據(jù),method屬性指明表單的提交方式申屹,分為get和post绘证,默認(rèn)為get-->
<form action="${pageContext.request.contextPath}/servlet/RequestDemo03" method="post">
<!--輸入文本框,SIZE表示顯示長度哗讥,maxlength表示最多輸入長度-->
編 號(文本框):
<input type="text" name="userid" value="NO." size="2" maxlength="2"><br>
<!--輸入文本框嚷那,通過value指定其顯示的默認(rèn)值-->
用戶名(文本框):<input type="text" name="username" value="請輸入用戶名"><br>
<!--密碼框,其中所有輸入的內(nèi)容都以密文的形式顯示-->
密 碼(密碼框):
<!-- 表示的是一個(gè)空格-->
<input type="password" name="userpass" value="請輸入密碼"><br>
<!--單選按鈕杆煞,通過checked指定默認(rèn)選中魏宽,名稱必須一樣,其中value為真正需要的內(nèi)容-->
性 別(單選框):
<input type="radio" name="sex" value="男" checked>男
<input type="radio" name="sex" value="女">女<br>
<!--下拉列表框决乎,通過<option>元素指定下拉的選項(xiàng)-->
部 門(下拉框):
<select name="dept">
<option value="技術(shù)部">技術(shù)部</option>
<option value="銷售部" SELECTED>銷售部</option>
<option value="財(cái)務(wù)部">財(cái)務(wù)部</option>
</select><br>
<!--復(fù)選框队询,可以同時(shí)選擇多個(gè)選項(xiàng),名稱必須一樣构诚,其中value為真正需要的內(nèi)容-->
興 趣(復(fù)選框):
<input type="checkbox" name="inst" value="唱歌">唱歌
<input type="checkbox" name="inst" value="游泳">游泳
<input type="checkbox" name="inst" value="跳舞">跳舞
<input type="checkbox" name="inst" value="編程" checked>編程
<input type="checkbox" name="inst" value="上網(wǎng)">上網(wǎng)
<br>
<!--大文本輸入框蚌斩,寬度為34列,高度為5行-->
說 明(文本域):
<textarea name="note" cols="34" rows="5">
</textarea>
<br>
<!--隱藏域范嘱,在頁面上無法看到送膳,專門用來傳遞參數(shù)或者保存參數(shù)-->
<input type="hidden" name="hiddenField" value="hiddenvalue"/>
<!--提交表單按鈕,當(dāng)點(diǎn)擊提交后丑蛤,所有填寫的表單內(nèi)容都會(huì)被傳輸?shù)椒?wù)器端-->
<input type="submit" value="提交(提交按鈕)">
<!--重置表單按鈕叠聋,當(dāng)點(diǎn)擊重置后,所有表單恢復(fù)原始顯示內(nèi)容-->
<input type="reset" value="重置(重置按鈕)">
</form>
<!--表單結(jié)束-->
</fieldset>
</body>
<!--完結(jié)標(biāo)記-->
</html>
<!--完結(jié)標(biāo)記-->
在Form表單中填寫數(shù)據(jù)受裹,然后提交到RequestDemo03這個(gè)Servlet進(jìn)行處理晒奕,填寫的表單數(shù)據(jù)如下:
在服務(wù)器端使用getParameter方法和getParameterValues方法接收表單參數(shù),代碼如下:
package gacl.request.study;
import java.io.IOException;
import java.text.MessageFormat;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author gacl
* 獲取客戶端通過Form表單提交上來的參數(shù)
*/
public class RequestDemo03 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//客戶端是以UTF-8編碼提交表單數(shù)據(jù)的,所以需要設(shè)置服務(wù)器端以UTF-8的編碼進(jìn)行接收脑慧,否則對于中文數(shù)據(jù)就會(huì)產(chǎn)生亂碼
request.setCharacterEncoding("UTF-8");
/**
* 編 號(文本框):
<input type="text" name="userid" value="NO." size="2" maxlength="2">
*/
String userid = request.getParameter("userid");//獲取填寫的編號魄眉,userid是文本框的名字,<input type="text" name="userid">
/**
* 用戶名(文本框):<input type="text" name="username" value="請輸入用戶名">
*/
String username = request.getParameter("username");//獲取填寫的用戶名
/**
* 密 碼(密碼框):<input type="password" name="userpass" value="請輸入密碼">
*/
String userpass = request.getParameter("userpass");//獲取填寫的密碼
String sex = request.getParameter("sex");//獲取選中的性別
String dept = request.getParameter("dept");//獲取選中的部門
//獲取選中的興趣闷袒,因?yàn)榭梢赃x中多個(gè)值坑律,所以獲取到的值是一個(gè)字符串?dāng)?shù)組,因此需要使用getParameterValues方法來獲取
String[] insts = request.getParameterValues("inst");
String note = request.getParameter("note");//獲取填寫的說明信息
String hiddenField = request.getParameter("hiddenField");//獲取隱藏域的內(nèi)容
String instStr="";
/**
* 獲取數(shù)組數(shù)據(jù)的技巧囊骤,可以避免insts數(shù)組為null時(shí)引發(fā)的空指針異常錯(cuò)誤晃择!
*/
for (int i = 0; insts!=null && i < insts.length; i++) {
if (i == insts.length-1) {
instStr+=insts[i];
}else {
instStr+=insts[i]+",";
}
}
String htmlStr = "<table>" +
"<tr><td>填寫的編號:</td><td>{0}</td></tr>" +
"<tr><td>填寫的用戶名:</td><td>{1}</td></tr>" +
"<tr><td>填寫的密碼:</td><td>{2}</td></tr>" +
"<tr><td>選中的性別:</td><td>{3}</td></tr>" +
"<tr><td>選中的部門:</td><td>{4}</td></tr>" +
"<tr><td>選中的興趣:</td><td>{5}</td></tr>" +
"<tr><td>填寫的說明:</td><td>{6}</td></tr>" +
"<tr><td>隱藏域的內(nèi)容:</td><td>{7}</td></tr>" +
"</table>";
htmlStr = MessageFormat.format(htmlStr, userid,username,userpass,sex,dept,instStr,note,hiddenField);
response.setCharacterEncoding("UTF-8");//設(shè)置服務(wù)器端以UTF-8編碼輸出數(shù)據(jù)到客戶端
response.setContentType("text/html;charset=UTF-8");//設(shè)置客戶端瀏覽器以UTF-8編碼解析數(shù)據(jù)
response.getWriter().write(htmlStr);//輸出htmlStr里面的內(nèi)容到客戶端瀏覽器顯示
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
運(yùn)行結(jié)果如下:
在服務(wù)器端使用getParameterNames方法 接收表單參數(shù),代碼如下:
Enumeration<String> paramNames = request.getParameterNames();//獲取所有的參數(shù)名
while (paramNames.hasMoreElements()) {
String name = paramNames.nextElement();//得到參數(shù)名
String value = request.getParameter(name);//通過參數(shù)名獲取對應(yīng)的值
System.out.println(MessageFormat.format("{0}={1}", name,value));
}
運(yùn)行結(jié)果如下:
在服務(wù)器端使用getParameterMap方法 接收表單參數(shù)也物,代碼如下:
//request對象封裝的參數(shù)是以Map的形式存儲(chǔ)的
Map<String, String[]> paramMap = request.getParameterMap();
for(Map.Entry<String, String[]> entry :paramMap.entrySet()){
String paramName = entry.getKey();
String paramValue = "";
String[] paramValueArr = entry.getValue();
for (int i = 0; paramValueArr!=null && i < paramValueArr.length; i++) {
if (i == paramValueArr.length-1) {
paramValue+=paramValueArr[i];
}else {
paramValue+=paramValueArr[i]+",";
}
}
System.out.println(MessageFormat.format("{0}={1}", paramName,paramValue));
}
運(yùn)行結(jié)果如下:
三宫屠、request接收表單提交中文參數(shù)亂碼問題
3.1、以POST方式提交表單中文參數(shù)的亂碼問題
例如有如下的form表單頁面:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>request接收中文參數(shù)亂碼問題</title>
</head>
<body>
<form action="<%=request.getContextPath()%>/servlet/RequestDemo04" method="post">
用戶名:<input type="text" name="userName"/>
<input type="submit" value="post方式提交表單">
</form>
</body>
</html>
此時(shí)在服務(wù)器端接收中文參數(shù)時(shí)就會(huì)出現(xiàn)中文亂碼滑蚯,如下所示:
3.2浪蹂、post方式提交中文數(shù)據(jù)亂碼產(chǎn)生的原因和解決辦法
可以看到,
之所以會(huì)產(chǎn)生亂碼告材,就是因?yàn)榉?wù)器和客戶端溝通的編碼不一致造成的沉唠,因此解決的辦法是:在客戶端和服務(wù)器之間設(shè)置一個(gè)統(tǒng)一的編碼繁仁,之后就按照此編碼進(jìn)行數(shù)據(jù)的傳輸和接收艾君。
由于客戶端是以UTF-8字符編碼將表單數(shù)據(jù)傳輸?shù)椒?wù)器端的氛琢,因此服務(wù)器也需要設(shè)置以UTF-8字符編碼進(jìn)行接收,要想完成此操作疤剑,服務(wù)器可以直接使用ServletRequest接口繼承而來的"setCharacterEncoding(charset)"方法進(jìn)行統(tǒng)一的編碼設(shè)置滑绒。修改后的代碼如下:
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/**
* 客戶端是以UTF-8編碼傳輸數(shù)據(jù)到服務(wù)器端的,所以需要設(shè)置服務(wù)器端以UTF-8的編碼進(jìn)行接收隘膘,否則對于中文數(shù)據(jù)就會(huì)產(chǎn)生亂碼
*/
request.setCharacterEncoding("UTF-8");
String userName = request.getParameter("userName");
System.out.println("userName:"+userName);
}
使用request.setCharacterEncoding("UTF-8");設(shè)置服務(wù)器以UTF-8的編碼接收數(shù)據(jù)后疑故,此時(shí)就不會(huì)產(chǎn)生中文亂碼問題了,如下所示:
3.3棘幸、以GET方式提交表單中文參數(shù)的亂碼問題
例如有如下的form表單頁面:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>request接收中文參數(shù)亂碼問題</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/servlet/RequestDemo04" method="get">
姓名:<input type="text" name="name"/>
<input type="submit" value="get方式提交表單">
</form>
</body>
</html>
此時(shí)在服務(wù)器端接收中文參數(shù)時(shí)就會(huì)出現(xiàn)中文亂碼,如下所示:
那么這個(gè)中文亂碼問題又該如何解決呢倦零,是否可以通過request.setCharacterEncoding("UTF-8");設(shè)置服務(wù)器以UTF-8的編碼進(jìn)行接收這種方式來解決中文亂碼問題呢误续,注意,對于以get方式傳輸?shù)闹形臄?shù)據(jù)扫茅,通過request.setCharacterEncoding("UTF-8");這種方式是解決不了中文亂碼問題蹋嵌,如下所示:
3.4、get方式提交中文數(shù)據(jù)亂碼產(chǎn)生的原因和解決辦法
對于以get方式傳輸?shù)臄?shù)據(jù)葫隙,request即使設(shè)置了以指定的編碼接收數(shù)據(jù)也是無效的(至于為什么無效我也沒有弄明白)栽烂,默認(rèn)的還是使用ISO8859-1這個(gè)字符編碼來接收數(shù)據(jù),客戶端以UTF-8的編碼傳輸數(shù)據(jù)到服務(wù)器端,而服務(wù)器端的request對象使用的是ISO8859-1這個(gè)字符編碼來接收數(shù)據(jù)腺办,服務(wù)器和客戶端溝通的編碼不一致因此才會(huì)產(chǎn)生中文亂碼的焰手。解決辦法:
在接收到數(shù)據(jù)后,先獲取request對象以ISO8859-1字符編碼接收到的原始數(shù)據(jù)的字節(jié)數(shù)組怀喉,然后通過字節(jié)數(shù)組以指定的編碼構(gòu)建字符串书妻,解決亂碼問題。
代碼如下:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/**
*
* 對于以get方式傳輸?shù)臄?shù)據(jù)躬拢,request即使設(shè)置了以指定的編碼接收數(shù)據(jù)也是無效的躲履,默認(rèn)的還是使用ISO8859-1這個(gè)字符編碼來接收數(shù)據(jù)
*/
String name = request.getParameter("name");//接收數(shù)據(jù)
name =new String(name.getBytes("ISO8859-1"), "UTF-8") ;//獲取request對象以ISO8859-1字符編碼接收到的原始數(shù)據(jù)的字節(jié)數(shù)組,然后通過字節(jié)數(shù)組以指定的編碼構(gòu)建字符串聊闯,解決亂碼問題
System.out.println("name:"+name);
}
運(yùn)行結(jié)果如下:
3.5工猜、以超鏈接形式傳遞中文參數(shù)的亂碼問題
客戶端想傳輸數(shù)據(jù)到服務(wù)器,可以通過表單提交的形式菱蔬,也可以通過超鏈接后面加參數(shù)的形式篷帅,例如:
<a href="${pageContext.request.contextPath}/servlet/RequestDemo05?userName=gacl&name=徐達(dá)沛">點(diǎn)擊</a>
點(diǎn)擊超鏈接,數(shù)據(jù)是以get的方式傳輸?shù)椒?wù)器的汗销,所以接收中文數(shù)據(jù)時(shí)也會(huì)產(chǎn)生中文亂碼問題犹褒,而解決中文亂碼問題的方式與上述的以get方式提交表單中文數(shù)據(jù)亂碼處理問題的方式一致,如下所示:
1 String name = request.getParameter("name");
2 name =new String(name.getBytes("ISO8859-1"), "UTF-8");
另外弛针,需要提的一點(diǎn)就是
URL地址后面如果跟了中文數(shù)據(jù)叠骑,那么中文參數(shù)最好使用URL編碼進(jìn)行處理
,如下所示:
1 <a href="${pageContext.request.contextPath}/servlet/RequestDemo05?userName=gacl&name=<%=URLEncoder.encode("徐達(dá)沛", "UTF-8")%>">點(diǎn)擊</a>
----------------------------本文轉(zhuǎn)載于孤傲蒼狼的csdn博客javaweb學(xué)習(xí)總結(jié)(十)——HttpServletRequest對象(一)削茁。