HttpServletRequest

HttpServletRequest對象表明客戶端的請求,當客戶端經過HTTP協議訪問服務器時,HTTP請求頭中的全部信息都封裝在這個對象中,經過這個對象提供的方法,能夠得到客戶端請求的全部信息。html

得到客戶機信息                                                                       

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

經過request對象獲取客戶端請求信息web

public class RequestDemo01 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /**
         * 1.得到客戶機信息
         */
        String requestUrl = request.getRequestURL().toString();//獲得請求的URL地址
        String requestUri = request.getRequestURI();//獲得請求的資源
        String queryString = request.getQueryString();//獲得請求的URL地址中附帶的參數
        String remoteAddr = request.getRemoteAddr();//獲得來訪者的IP地址
        String remoteHost = request.getRemoteHost();
        int remotePort = request.getRemotePort();
        String remoteUser = request.getRemoteUser();
        String method = request.getMethod();//獲得請求URL地址時使用的方法
        String pathInfo = request.getPathInfo();
        String localAddr = request.getLocalAddr();//獲取WEB服務器的IP地址
        String localName = request.getLocalName();//獲取WEB服務器的主機名
        response.setCharacterEncoding("UTF-8");//設置將字符以"UTF-8"編碼輸出到客戶端瀏覽器
        //經過設置響應頭控制瀏覽器以UTF-8的編碼顯示數據,若是不加這句話,那麼瀏覽器顯示的將是亂碼
        response.setHeader("content-type", "text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.write("獲取到的客戶機信息以下:");
        out.write("<hr/>");
        out.write("請求的URL地址:"+requestUrl);
        out.write("<br/>");
        out.write("請求的資源:"+requestUri);
        out.write("<br/>");
        out.write("請求的URL地址中附帶的參數:"+queryString);
        out.write("<br/>");
        out.write("來訪者的IP地址:"+remoteAddr);
        out.write("<br/>");
        out.write("來訪者的主機名:"+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);
    }

}

download

得到客戶機請求頭                                                                    

getHeader(string name)方法:String
getHeaders(String name)方法:Enumeration
getHeaderNames()方法編程

/**
 * @author gacl
 * 獲取客戶端請求頭信息
 * 客戶端請求頭:
 * 
 */
public class RequestDemo02 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setCharacterEncoding("UTF-8");//設置將字符以"UTF-8"編碼輸出到客戶端瀏覽器
        //經過設置響應頭控制瀏覽器以UTF-8的編碼顯示數據
        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);//根據請求頭的名字獲取對應的請求頭的值
            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請求頭對應的值
        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);
    }

}

download

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

getParameter(String)方法(經常使用)設計模式

getParameterValues(String name)方法(經常使用)數組

getParameterNames()方法(不經常使用)瀏覽器

getParameterMap()方法(編寫框架時經常使用)服務器

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<fieldset style="width:500px;">
    <legend>Html的Form表單元素</legend>
    <form action="${pageContext.request.contextPath}/servlet/RequestDemo03" method="post">
&nbsp;&nbsp;號(文本框):<input type="text" name="userid" value="NO." size="2" maxlength="2"><br>
    用戶名(文本框):<input type="text" name="username" value="請輸入用戶名"><br>&nbsp;&nbsp;碼(密碼框):<input type="password" name="userpass" value="請輸入密碼"><br>
&nbsp;&nbsp;別(單選框):
    <input type="radio" name="sex" value="男" checked><input type="radio" name="sex" value="女"><br>
&nbsp;&nbsp;門(下拉框):
    <select name="dept">
        <option value="技術部">技術部</option>
        <option value="銷售部" SELECTED>銷售部</option>
        <option value="財務部">財務部</option>
    </select><br>
&nbsp;&nbsp;趣(複選框): 
    <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="上網">上網
    <br>
&nbsp;&nbsp;明(文本域):
    <textarea name="note" cols="34" rows="5">
     </textarea>
    <br>
    <input type="hidden" name="hiddenField" value="hiddenvalue"/>
    <input type="submit" value="提交(提交按鈕)">
    <input type="reset" value="重置(重置按鈕)">
</form>
<!--表單結束-->
</fieldset>

在服務器端使用getParameter方法和getParameterValues方法接收表單參數:網絡

/**
 * 獲取客戶端經過Form表單提交上來的參數
 */
public class RequestDemo03 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //客戶端是以UTF-8編碼提交表單數據的,因此須要設置服務器端以UTF-8的編碼進行接收,不然對於中文數據就會產生亂碼
        request.setCharacterEncoding("UTF-8");
        /**
         * 編&nbsp;&nbsp;號(文本框):
           <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");//獲取填寫的用戶名
        /**
         * 密&nbsp;&nbsp;碼(密碼框):<input type="password" name="userpass" value="請輸入密碼">
         */
        String userpass = request.getParameter("userpass");//獲取填寫的密碼
        String sex = request.getParameter("sex");//獲取選中的性別
        String dept = request.getParameter("dept");//獲取選中的部門
        //獲取選中的興趣,由於能夠選中多個值,因此獲取到的值是一個字符串數組,所以須要使用getParameterValues方法來獲取
        String[] insts = request.getParameterValues("inst");
        String note = request.getParameter("note");//獲取填寫的說明信息
        String hiddenField = request.getParameter("hiddenField");//獲取隱藏域的內容
        
        String instStr="";
        /**
         * 獲取數組數據的技巧,能夠避免insts數組爲null時引起的空指針異常錯誤!
         */
        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>隱藏域的內容:</td><td>{7}</td></tr>" +
                        "</table>";
        htmlStr = MessageFormat.format(htmlStr, userid,username,userpass,sex,dept,instStr,note,hiddenField);
        
        response.setCharacterEncoding("UTF-8");//設置服務器端以UTF-8編碼輸出數據到客戶端
        response.setContentType("text/html;charset=UTF-8");//設置客戶端瀏覽器以UTF-8編碼解析數據
        response.getWriter().write(htmlStr);//輸出htmlStr裏面的內容到客戶端瀏覽器顯示
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

在服務器端使用getParameterNames方法接收表單參數:框架

Enumeration<String> paramNames = request.getParameterNames();//獲取全部的參數名
         while (paramNames.hasMoreElements()) {
             String name = paramNames.nextElement();//獲得參數名
             String value = request.getParameter(name);//經過參數名獲取對應的值
             System.out.println(MessageFormat.format("{0}={1}", name,value));
         }

在服務器端使用getParameterMap方法接收表單參數:

//request對象封裝的參數是以Map的形式存儲的
        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));
        }

以POST方式提交表單中文參數的亂碼問題                                          

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
      <form action="<%=request.getContextPath()%>/servlet/RequestDemo04" method="post">
          用戶名:<input type="text" name="userName"/>
          <input type="submit" value="post方式提交表單"> 
      </form>

此時在服務器端接收中文參數時就會出現中文亂碼,以下所示:

download

post方式提交中文數據亂碼產生的緣由和解決辦法                                  

之因此會產生亂碼,就是由於服務器和客戶端溝通的編碼不一致形成的,所以解決的辦法是:在客戶端和服務器之間設置一個統一的編碼,以後就按照此編碼進行數據的傳輸和接收。

因爲客戶端是以UTF-8字符編碼將表單數據傳輸到服務器端的,所以服務器也須要設置以UTF-8字符編碼進行接收,要想完成此操做,服務器能夠直接使用從ServletRequest接口繼承而來的"setCharacterEncoding(charset)"方法進行統一的編碼設置。

public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /**
         * 客戶端是以UTF-8編碼傳輸數據到服務器端的,因此須要設置服務器端以UTF-8的編碼進行接收,不然對於中文數據就會產生亂碼
         */
        request.setCharacterEncoding("UTF-8");
        String userName = request.getParameter("userName");
        System.out.println("userName:"+userName);
}

使用request.setCharacterEncoding("UTF-8");設置服務器以UTF-8的編碼接收數據後,此時就不會產生中文亂碼問題了。

以GET方式提交表單中文參數的亂碼問題                                            

對於以get方式傳輸的數據,request即便設置了以指定的編碼接收數據也是無效的(至於爲何無效我也沒有弄明白),默認的仍是使用ISO8859-1這個字符編碼來接收數據,客戶端以UTF-8的編碼傳輸數據到服務器端,而服務器端的request對象使用的是ISO8859-1這個字符編碼來接收數據,服務器和客戶端溝通的編碼不一致所以纔會產生中文亂碼的。解決辦法:在接收到數據後,先獲取request對象以ISO8859-1字符編碼接收到的原始數據的字節數組,而後經過字節數組以指定的編碼構建字符串,解決亂碼問題。

public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /**
        * 對於以get方式傳輸的數據,request即便設置了以指定的編碼接收數據也是無效的,默認的仍是使用ISO8859-1這個字符編碼來接收數據
         */
        String name = request.getParameter("name");//接收數據
        name =new String(name.getBytes("ISO8859-1"), "UTF-8") ;//獲取request對象以ISO8859-1字符編碼接收到的原始數據的字節數組,而後經過字節數組以指定的編碼構建字符串,解決亂碼問題
        System.out.println("name:"+name);    
}

以超連接形式傳遞中文參數的亂碼問題                                              

客戶端想傳輸數據到服務器,能夠經過表單提交的形式,也能夠經過超連接後面加參數的形式:

<a href="${pageContext.request.contextPath}/servlet/RequestDemo05?userName=gacl&name=張三">點擊</a>

點擊超連接,數據是以get的方式傳輸到服務器的,因此接收中文數據時也會產生中文亂碼問題,而解決中文亂碼問題的方式與上述的以get方式提交表單中文數據亂碼處理問題的方式一致,以下所示:

String name = request.getParameter("name");
name =new String(name.getBytes("ISO8859-1"), "UTF-8");

另外,須要提的一點就是URL地址後面若是跟了中文數據,那麼中文參數最好使用URL編碼進行處理

<a href="${pageContext.request.contextPath}/servlet/RequestDemo05?userName=gacl&name=<%=URLEncoder.encode("張三", "UTF-8")%>">點擊</a>

提交中文數據亂碼問題總結                                                          

一、若是提交方式爲post,想不亂碼,只須要在服務器端設置request對象的編碼便可,客戶端以哪一種編碼提交的,服務器端的request對象就以對應的編碼接收,好比客戶端是以UTF-8編碼提交的,那麼服務器端request對象就以UTF-8編碼接收(request.setCharacterEncoding("UTF-8"))

二、若是提交方式爲get,設置request對象的編碼是無效的,request對象仍是以默認的ISO8859-1編碼接收數據,所以要想不亂碼,只能在接收到數據後再手工轉換,步驟以下:

1).獲取獲取客戶端提交上來的數據,獲得的是亂碼字符串,data="???è?????"

String data = request.getParameter("paramName");

2).查找ISO8859-1碼錶,獲得客戶機提交的原始數據的字節數組

byte[] source = data.getBytes("ISO8859-1");

3).經過字節數組以指定的編碼構建字符串,解決亂碼

data = new String(source, "UTF-8");

經過字節數組以指定的編碼構建字符串,這裏指定的編碼是根據客戶端那邊提交數據時使用的字符編碼來定的,若是是GB2312,那麼就設置成data = new String(source, "GB2312"),若是是UTF-8,那麼就設置成data = new String(source, "UTF-8")

請求轉發的基本概念                                                                  

請求轉發:指一個web資源收到客戶端請求後,通知服務器去調用另一個web資源進行處理。
  請求轉發的應用場景:MVC設計模式

  在Servlet中實現請求轉發的兩種方式:

一、經過ServletContext的getRequestDispatcher(String path)方法,該方法返回一個RequestDispatcher對象,調用這個對象的forward方法能夠實現請求轉發。

例如:將請求轉發的test.jsp頁面

RequestDispatcher reqDispatcher =this.getServletContext().getRequestDispatcher("/test.jsp");
reqDispatcher.forward(request, response);

二、經過request對象提供的getRequestDispatche(String path)方法,該方法返回一個RequestDispatcher對象,調用這個對象的forward方法能夠實現請求轉發。

例如:將請求轉發的test.jsp頁面

request.getRequestDispatcher("/test.jsp").forward(request, response);

request對象同時也是一個域對象(Map容器),開發人員經過request對象在實現轉發時,把數據經過request對象帶給其它web資源處理。

例如:請求RequestDemo06 Servlet,RequestDemo06將請求轉發到test.jsp頁面

public class RequestDemo06 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String data="拉拉";
        /**
         * 將數據存放到request對象中,此時把request對象看成一個Map容器來使用
         */
        request.setAttribute("data", data);
        //客戶端訪問RequestDemo06這個Servlet後,RequestDemo06通知服務器將請求轉發(forward)到test.jsp頁面進行處理
        request.getRequestDispatcher("/test.jsp").forward(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

test.jsp頁面代碼以下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Request對象實現請求轉發</title>
  </head>
  
  <body>
      使用普通方式取出存儲在request對象中的數據:
      <h3 style="color:red;"><%=(String)request.getAttribute("data")%></h3>
     使用EL表達式取出存儲在request對象中的數據:
     <h3 style="color:red;">${data}</h3>
  </body>
</html>

request對象做爲一個域對象(Map容器)使用時,主要是經過如下的四個方法來操做

  • setAttribute(String name,Object o)方法,將數據做爲request對象的一個屬性存放到request對象中,例如:request.setAttribute("data", data);
  • getAttribute(String name)方法,獲取request對象的name屬性的屬性值,例如:request.getAttribute("data")
  • removeAttribute(String name)方法,移除request對象的name屬性,例如:request.removeAttribute("data")
  • getAttributeNames方法,獲取request對象的全部屬性名,返回的是一個,例如:Enumeration<String> attrNames = request.getAttributeNames();

請求重定向和請求轉發的區別                                                        

一個web資源收到客戶端請求後,通知服務器去調用另一個web資源進行處理,稱之爲請求轉發/307。
一個web資源收到客戶端請求後,通知瀏覽器去訪問另一個web資源進行處理,稱之爲請求重定向/302。

我是天王蓋地虎的分割線                                                             

 

 

參考:http://www.cnblogs.com/xdp-gacl/p/3798347.html

相關文章
相關標籤/搜索