--------------------------HttpServletRequest參數獲取,HttpServletRequest詳解---------------------------------
HttpServletRequest獲取參數(重要)
1 HttpServletRequest獲取參數方法
可以使用HttpServletRequest獲取客戶端的請求參數,相關方法如下:
String getParameter(String name):通過指定名稱獲取參數值;
String[] getParameterValues(String name):通過指定名稱獲取參數值數組,有可能一個名字對應多個值,例如表單中的多個復選框使用相同的name時;
Enumeration getParameterNames():獲取所有參數的名字;
Map getParameterMap():獲取所有參數對應的Map,其中key為參數名,value為參數值。
2 傳遞參數的方式
傳遞參數的方式:GET和POST。
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暫不介紹
3. 單值參數的接收
單值參數包括單選,單值下拉框,文本,隱藏域
無論是GET還是POST,獲取參數的方法是相同的。
String s1 = request.getParameter(“p1”);//返回v1
String s2 = request.getParameter(“p2”);//返回v2
<form action="ParamServlet" method="post">
<input type="text" name="p1"/><br/>
<input type="text" name="p2"/><br/>
<input type="submit" value="提交"/><br/>
</form>
<a href="ParamServlet?p1=v1&p2=v2">Param</a>
String s1 = request.getParameter("p1");
String s2 = request.getParameter("p2");
response.getWriter().print("p1 = " + s1 + "<br/>");
response.getWriter().print("p2 = " + s2 + "<br/>");
Enumeration names = request.getParameterNames();
while(names.hasMoreElements()) {
String name = (String)names.nextElement();
String value = request.getParameter(name);
System.out.println(name + " = " + value);
}
4 多值參數接收
多值參數主要就是多選checkbox
例如在注冊表單中,如果讓用戶填寫愛好,那么愛好可能就是多個。那么hobby參數就會對應多個值:
<form action="ParamServlet" method="post">
上網:<input type="checkbox" name="hobby" value="netplay" /><br/>
踢球:<input type="checkbox" name="hobby" value="football" /><br/>
看書:<input type="checkbox" name="hobby" value="read" /><br/>
編程:<input type="checkbox" name="hobby" value="programme" /><br/>
<input type="submit" value="提交"/><br/>
</form>
// 獲取所有名為hoby的參數值
String[] hobbies = request.getParameterValues("hobby");
System.out.println(Arrays.toString(hobbies));
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)獲取,其實當參數的值是單個的時候,同樣可以使用request.getParameterValues(String)方法來獲取參數值,不過這個參數返回的值為String[],這時我們需要再去獲取數組下標0的元素。
String name = request.getParameterValues(“name”)[0];
在知道name的情況下,獲取單值和多值的代碼示例:
代碼1.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>request接收參數</h1>
<a href="/request_demo2/hello?name=likunpeng&age=30">訪問1.html</a>
<hr/>
<h1>表單方式來提交數據</h1>
<form action="/request_demo2/hello" method="get">
姓名:<input name="name" type="text">
<br/>
年齡:<input name="age" type="text">
<br/>
性別:<input name="gender" type= "radio" value="1">男
<input name="gender" type="radio" value="0">女
<br/>
職位:<select name="job">
<option value="1">講師</option>
<option value="2">架構師</option>
</select>
<br/>
簡介:<br/>
<textarea name="introduce" rows="10" cols="30"></textarea>
<br/>
愛好:<input name="favor" type="checkbox" value="1">籃球
<input name="favor" type="checkbox" value="2">足球
<input name="favor" type="checkbox" value="3">游泳
<br/>
<input type="submit" value="提交">
</form>
</body>
</html>
HelloServlet代碼:
public class HelloServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//根據請求中的key來獲得值
//單值接收
String name = request.getParameter("name");
System.out.println(name);
String age = request.getParameter("age");
System.out.println(age);
String gender = request.getParameter("gender");
System.out.println(gender);
String job = request.getParameter("job");
System.out.println(job);
String introduce = request.getParameter("introduce");
System.out.println(introduce);
//以下方式不適合接收多選,只能接收到多選中的第一個
//String favor = request.getParameter("favor");
//多值接收
String[] favors = request.getParameterValues("favor");
for (String favo : favors) {
System.out.print(favor+"、");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
結果圖
-------------------------------------------------------------------------------------------------------------
在不知道name的情況下,通過request中的getParameterNames方法來獲取文本域中的值:
新建一個servlet
public class HelloServlet1 extends HttpServlet {
/**
* getParameterNames用於獲得表單中文本域的所有的name,適合動態表單
*/
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲得表單中所有的文本域的name
Enumeration<String> parameteNames = request.getParameterNames();
while(parameteNames.hasMoreElements()){
//獲得每個文本域的name
String parameteName = parameteNames.nextElement();
//根據文本域的name來獲取值
//因為無法判斷文本域是否是單值或者雙值,所以我們全部使用雙值接收
String[] parameteValues = request.getParameterValues(parameteName);
//輸出文本域的name
System.out.print(parameteName+":");
for (String parameteValue : parameteValues) {
//輸出文本域的值
System.out.print(parameteValue+" ");
}
//換行
System.out.println();
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
-------------------------------------------------------------------
Request中getParameterMap使用介紹:
Servlet代碼示例:
public class HelloServlet2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲得表單中所有文本域的name和值,以Map方式來存取
Map map = request.getParameterMap();
//獲得Map集合中所有的key,就是表單中文本域的集合
Set<String> keys = map.keySet();
for (String name : keys) {
//獲得文本域的值
String[] values = (String[])map.get(name);
//打印文本域名字
System.out.print(name+":");
for (String value : values) {
//打印文本域中的值
System.out.print(value+" ");
}
//打印換行
System.out.println();
}
}
}
5.Request的獲得中文亂碼處理
設置eclipse所使用的編碼:
Request接收參數時有get和post兩種請求方式,但是處理中文的編碼卻不一樣,我們在做項目時會全站都采用統一的編碼,最常用的就是UTF-8,在UTF-8編碼的項目中的
當我們使用Post請求時:
處理POST編碼問題!
我們知道,請求信息中,只有POST存在正文,所謂POST參數編碼就是就是請求正文的編碼。
默認情況下,使用getParameter()獲取POST請求參數時,使用的是ISO-8859-1編碼。
String name = request.getParameter("name");
name = new String(name.getBytes("ISO-8859-1"), "UTF-8");
System.out.println(name);
因為在獲取參數時已經被錯誤的編碼了,但因為我們知道,亂碼的兩個原因:本來是使用UTF-8編碼的,還錯誤的使用了ISO-8859-1編碼。所以我們可以先使用ISO-8859-1獲取字節數組,然后再使用正確的UTF-8編碼得到字符串,這樣就沒問題了。
request的setCharacterEncodng()可以設置編碼,當然這必須在調用所有的getParameter()方法之前調用request的setCharacterEncodng()方法來設置編碼,這樣,就不會使用ISO解讀字節串了,而是使用你給定的編碼來解讀。
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
System.out.println(name);
對於每個請求,只需要調用request的setCharacterEncodng()一次,然后所有getParameter()都會使用這個編碼來解讀參數。但要注意,只對請求正文有效,即POST參數。
字符串編碼案例介紹:
public class test {
public static void main(String[] args) throws UnsupportedEncodingException {
//獲取一個ISO-8869-1編碼的字符串
String s = new String("李昆鵬".getBytes(),"ISO-8859-1");
//指定s的編碼格式為ISO-8859-1,s的解碼格式為默認格式UTF-8,s1的編碼格式為默認格式UTF-8
String s1 = new String(s.getBytes("ISO-8859-1"));
//指定s的編碼格式為ISO-8859-1,s的解碼格式為默認格式UTF-8,s1的編碼格式為指定格式UTF-8
String s2 = new String(s.getBytes("ISO-8859-1"),"UTF-8");
//指定s的編碼格式為默認格式UTF-8,s的解碼格式為默認格式UTF-8,s1的編碼格式為指定格式UTF-8
String s3 = new String(s.getBytes(),"UTF-8");
//請看輸出結果
System.out.println(s); //ææé¹
System.out.println(s1);//李昆鵬
System.out.println(s2);//李昆鵬
System.out.println(s3);//ææé¹
}
}
Post方式處理中文亂碼第一種方式:
public class HelloServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
String introduce = request.getParameter("introduce");
//以下輸出字符串會出現亂碼
System.out.println(name);
System.out.println(introduce);
//將name編碼通過string構造器從ISO-8859-1變成UTF-8解碼
name = new String(name.getBytes("ISO-8859-1"),"UTF-8");
introduce = new String(introduce.getBytes("ISO-8859-1"),"UTF-8");
System.out.println(name);
System.out.println(introduce);
}
}
Post方式處理中文亂碼第二種方式: 使用request中的setCharacterEncoding(“UTF-8”)方法(建議使用)
public class HelloServlet1 extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//設置request編碼為UTF-8
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
String introduce = request.getParameter("introduce");
System.out.println(name);
System.out.println(introduce);
}
}
當我們采用get請求時
上述的post的處理方式不再生效
第一種方式:
我們可以采用字符串轉碼的方式來處理
String s = request.getParameter(“s”);
s = new String(s.getBytes(“iso-8859-1”), “utf-8”);
第二種方式:
GET參數不在請求正文中,而是在URL中。所以不能使用request的setCharacterEncodng()來設置GET參數的編碼。
處理GET參數編碼可以有兩種方式:第一種是設置<Connector>元素的URIEncoding屬性的值為UTF-8。即conf\server.xml中的<Connector>元素的URIEncoding屬性。
一旦設置了這個屬性,那么對於GET參數就直接是UTF-8編碼的了。但是,<Connector>元素來說,對整個Tomcat都是有效的!
第三種JavaScript對超鏈接做URL編碼
處理這個問題的辦法是把GET請求中的參數使用JavaScript做URL編碼,URL編碼后的內容就不再是中文了,這樣IE6也就不會丟失字節了。
<a href="#" onclick="click1()">ff</a>
<script type="text/javascript">
function click1(){
var path = encodeURI(encodeURI("servlet/RequestDemo?namea=任亮"));
location.href = path;
}
</script>
http://localhost/encoding/EncodingServlet?name=%E5%A4%A7%E5%AE%B6%E5%A5%BD
在使用URL編碼后,大家好已經變成了%E5%A4%A7%E5%AE%B6%E5%A5%BD。這樣就不會再丟失字節了。
String val = request.getParameter("namea");
val = URLDecoder.decode(val, "UTF-8");
System.out.println(val);
代碼1.xml示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function subreq(){
var path = encodeURI(encodeURI("/request_demo3/hello3?name=李昆鵬1"));
window.location.href=path;
}
</script>
</head>
<body>
<h1>request接收參數</h1>
<a href="/request_demo2/hello?name=likunpeng&age=30">訪問1.html</a>
<hr/>
<h1>request處理post方式中文亂碼問題</h1>
<form action="/request_demo3/hello1" method="post">
姓名:<input name="name" type="text">
<br/>
年齡:<input name="age" type="text">
<br/>
簡介:<br/>
<textarea name="introduce" rows="10" cols="30"></textarea>
<br/>
<input type="submit" value="提交">
</form>
<hr/>
<h1>request處理get方式中文亂碼問題</h1>
<a href="/request_demo3/hello2?name=李昆鵬&introduce=你好">點擊Get請求</a>
<br/>
<a href="#" οnclick="subreq()">點擊Get請求1</a>
</body>
</html>
HelloServlet3代碼示例:
public class HelloServlet3 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//設置request編碼為UTF-8
//在get方式請求中request.setCharacterEncoding("UTF-8");不再起作用
String name = request.getParameter("name");
//下面是第一種解決get方式中文亂碼問題
//name = new String(name.getBytes("ISO-8859-1"),"UTF-8");
//第二種方式在服務器配置文件server.xml的Connector元素中添加編碼屬性URIEncoding="UTF-8"
//第三種方式利用javaScript解決中文亂碼問題
name = URLDecoder.decode(name,"UTF-8");
System.out.println(name);
}
}
6. HttpServletRequest請求轉發(服務器端跳轉forward)
在Servlet中請求轉發是大量要使用的,因為當我們訪問一個Servlet的時候通常會執行一些后台的業務邏輯,然后跳轉到一個結果頁面,那么跳轉到結果頁面的這個過程就是請求轉發,舉個例子我們做登錄的功能,我們填寫用戶名密碼然后提交到一個負責登錄的Servlet,Servlet為我們做用戶名和密碼的校驗,如果我們都正確的話,我們就要跳轉到登錄的提示頁面,如果錯誤就要跳轉到登錄失敗的頁面。
Request的請求轉發也可以叫做服務器端的跳轉,雖然有頁面的跳轉但是我們會發現地址欄是不會有變化的。
request.getRequestDispatcher("/success.html").forward(request, response);
我們不但可以跳轉到靜態頁面(后續主要講解是動態頁面我們通常會跳轉到一個jsp(jsp在Servlet之后產生)的提示頁面,因為我們要返回的是動態頁面,所有html是不適合(后續講解))。還可以跳轉到Servlet,此時我們可以給request來設置當前域中的屬性值,在該域之內(當前請求完成之前)都能獲得到該屬性值。
request.setAttribute("name", "任亮");
request.getAttribute("name");
Servlet內部頁面跳轉代碼示例:
代碼1.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>請求轉發</title>
</head>
<body>
<h1>請求轉發到success.html頁面</h1>
<form action="/request_demo4/hello" method="post">
姓名:<input name="name" type="text">
<br/>
年齡:<input name="age" type="text">
<br/>
簡介:<br/>
<textarea name="introduce" rows="10" cols="30"></textarea>
<br/>
<input type="submit" value="提交">
</form>
<h1>請求轉發到servlet</h1>
<form action="/request_demo4/hello" method="post">
姓名:<input name="name" type="text">
<br/>
年齡:<input name="age" type="text">
<br/>
簡介:<br/>
<textarea name="introduce" rows="10" cols="30"></textarea>
<br/>
<input type="submit" value="提交">
</form>
<hr/>
</body>
</html>
HelloServlet代碼:
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* request請求轉發
* 服務器的頁面跳轉,地址欄不變
*/
System.out.println("servlet被訪問");
//使用request.setAttribute來設置結果集
request.setAttribute("testAttribute", new String[]{"li","kun","peng"});
request.getRequestDispatcher("/hello1").forward(request, response);
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
HelloServlet1代碼:
public class HelloServlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* request請求轉發
* 服務器的頁面跳轉,地址欄不變
*/
System.out.println("servlet1被訪問");
String[] attributeValues = (String[])request.getAttribute("testAttribute");
for (String attributeValue : attributeValues) {
System.out.println(attributeValue);
}
request.getRequestDispatcher("/success.html").forward(request, response);
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
7.request域的作用范圍
在上一講我們提及過ServletContext的概念,它也是一個域的對象,它的范圍非常大,是指定項目所有Servlet的公共的對象,隨着服務器的啟動而產生,服務器的停止而銷毀,那么request的也是域對象,它的作用范圍小的多,它的范圍只在一次請求響應范圍之內,每一個線程的請求都會新產生一個HttpServletRequest和HttpServletResponse的對象
————————————————
版權聲明:本文為CSDN博主「李昆鵬」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_41547486/article/details/81266712