HttpServletRequest參數獲取,HttpServletRequest詳解

--------------------------HttpServletRequest參數獲取,HttpServletRequest詳解---------------------------------

HttpServletRequest獲取參數(重要)

1 HttpServletRequest獲取參數方法

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

  1. String getParameter(String name):通過指定名稱獲取參數值;
  2. String[] getParameterValues(String name):通過指定名稱獲取參數值數組,有可能一個名字對應多個值,例如表單中的多個複選框使用相同的name時;
  3. Enumeration getParameterNames():獲取所有參數的名字;
  4. Map getParameterMap():獲取所有參數對應的Map,其中key爲參數名,value爲參數值。

 

2 傳遞參數的方式

傳遞參數的方式:GET和POST。

GET:

  1. 地址欄中直接給出參數:http://localhost/param/ParamServlet?p1=v1&p2=v2;
  2. 超鏈接中給出參數:<a href=” http://localhost/param/ParamServlet?p1=v1&p2=v2”>???</a>
  3. 表單中給出參數:<form method=”GET” action=”ParamServlet”>…</form>
  4. Ajax暫不介紹

 

POST:

  1. 表單中給出參數:<form method=”POST” action=”ParamServlet”>…</form>
  2. 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">男&nbsp;

                  <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">籃球&nbsp;

                  <input name="favor" type="checkbox" value="2">足球&nbsp;

                     <input name="favor" type="checkbox" value="3">游泳&nbsp;

                     <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編碼的項目中的

  1. 當我們使用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的對象

 

發佈了205 篇原創文章 · 獲贊 125 · 訪問量 27萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章