JavaWeb(一)Servlet中的request與response

1、HttpServletRequest概述

1.一、HttpServletRequest簡介

  HttpServletRequest對象表明 客戶端的請求,當客戶端經過HTTP協議訪問服務器時,HTTP請求頭中的全部信息都封裝在這個對象中,開發人員經過這個對象的方法,能夠得到客戶這些信息。
  request就是 將請求文本封裝而成的對象,因此經過request能得到請求文本中的全部內容,請求頭、請求體、請求行
    

2、詳解HttpServletRequest

2.一、請求行

  舉例: Get  http://localhost:8080/day09/servlet/req1?username=zs  http/1.1
  相關方法:
    getMethod();     得到請求方式
    getRequestURL();    返回客戶端發出請求時的完整URL。
    getRequestURI();    返回請求行中的資源名部分。
    getContextPath();    當前應用的虛擬目錄 
    getQueryString() ;    返回請求行中的參數部分。
//        getMethod(); 得到請求方式
//        ***getRequestURL();返回客戶端發出請求時的完整URL。
//        ***getRequestURI(); 返回請求行中的資源名部分。
//        *****getContextPath(); 當前應用的虛擬目錄 /day09_01_HttpServletRequest
//        getQueryString() ; 返回請求行中的參數部分。
        
        System.out.println(request.getMethod());//  GET
        System.out.println(request.getRequestURL()); // http://localhost:8080/day09_01_HttpServletRequest/servlet/demo1
        System.out.println(request.getRequestURI()); //   /day09_01_HttpServletRequest/servlet/demo1
        System.out.println(request.getContextPath()); //  /day09_01_HttpServletRequest
        System.out.println(request.getQueryString()); //  username=tom
舉例

   舉例二:Get  http://localhost:6060/Web_Servlet/ServletTest3?username=faker&password=mid  http/1.1html

  相關方法:java

    getRequestURI();
    getRequestURL();
    getProtocol(); 
    getScheme();
    getServerName();
    getServerPort();
    getContextPath();
    getServletPath();
    getQueryString();
    getRemoteAddr(); web

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.統一資源標記符   /Web_Servlet/ServletTest3
        String uri = req.getRequestURI();
        System.out.println(uri);
        //2.統一資源定位符    http://localhost:6060/Web_Servlet/ServletTest3 
        StringBuffer url = req.getRequestURL();
        System.out.println(url);
        //3.協議和版本    HTTP/1.1
        String potocol = req.getProtocol();
        System.out.println(potocol);
        //4.協議    http
        String scheme = req.getScheme();
        System.out.println(scheme);
        //5.主機(域名)  localhost,若是你使用的是ip地址,就顯示ip地址
        String serverName = req.getServerName();
        System.out.println(serverName);
        //6.端口  6060(這是我本身修改了的端口,默認是8080)
        int port = req.    getServerPort();
        System.out.println(port);
        //7.發佈到tomcat下的項目名稱  /Web_Servlet
        String contextPath = req.getContextPath();
        System.out.println(contextPath);
        //8.servlet路徑    /ServletTest3 
        String servletPath = req.getServletPath();
        System.out.println(servletPath);
        //9.獲取全部請求參數,即?以後全部東西。    username=faker&password=mid
        String queryString = req.getQueryString();
        System.out.println(queryString);
        //10.遠程主機的ip地址    0:0:0:0:0:0:0:1
        String remoteAddr = req.getRemoteAddr();
        System.out.println(remoteAddr);
        
        
    }
舉例二

2.二、請求頭  

  咱們能夠查看任意一個網頁,它都是有請求頭的。apache

  

  相關方法: 編程

    String getHeader(String name) 根據頭名稱獲得頭信息值瀏覽器

    long getDateHeader(java.lang.String name) 得到指定頭內容Date緩存

    int getIntHeader(java.lang.String name)  得到指定頭內容inttomcat

    Enumeration getHeaderNames() 獲得全部頭信息name
    Enumeration getHeaders(String name) 根據頭名稱獲得相同名稱頭信息值安全

  舉例1:Enumeration getHeaderNames() 獲得全部頭信息name 服務器

Enumeration<String> headerNames = req.getHeaderNames();
        while(headerNames.hasMoreElements()){
            String key = (String)headerNames.nextElement();
            String value = req.getHeader(key);
            System.out.println(key+"="+value);
        } 

  結果:

    

  舉例2:Enumeration getHeaders(String name) 根據頭名稱獲得相同名稱頭信息值

        Enumeration<String> headers = req.getHeaders("accept-language");
        while(headers.hasMoreElements()){
            String key = (String)headers.nextElement();
            String value = req.getHeader(key);
            System.out.println(key+"==="+value);
            
        }

  結果:

    

2.三、請求體(請求正文)

  1)與表單獲取相關的方法

  方法:    

    String getParameter(name)   根據表單中name屬性的名,獲取value屬性的值方法
    String[] getParameterValues(String name)  專爲複選框取取提供的方法
    getParameterNames()   獲得表單提交的全部name的方法
    Map<String , String[]> getParameterMap()   獲得表單提交的全部值的方法 //作框架用,很是實用
    getInputStream    以字節流的方式獲得全部表單數據

  舉例:   

<form action="/day09_01_HttpServletRequest/servlet/demo3" method="get">
        用戶名:<input type="text" name="userName"/><br/>
        密碼:<input type="password" name="pwd"/><br/>
        性別:<input type="radio" name="sex" value="" checked="checked"/><input type="radio" name="sex" value=""/>女  <br/>
        愛好 :
            <input type="checkbox" name="hobby" value="籃球"/>籃球
            <input type="checkbox" name="hobby" value="唱歌"/>唱歌
            <input type="checkbox" name="hobby" value="編碼"/>編碼
            <br/>
        所在城市:
        <select name="city">
            <option>------請選擇------</option>
            <option value="bj">北京</option>
            <option value="sh">上海</option>
            <option value="gz">廣州</option>
        </select>
        <br/>
        
        <input type="submit" value="註冊"/>
    </form>
舉例

  測試1使用方法:   

    <input type="text" name="username" />
     getParameter(name) 根據表單中name屬性的名,獲取value屬性的值方法 
    getParameterValues(String name)專業爲複選框取取提供的方法
//獲取表單數據
        
        //根據表單中name屬性的名,獲取value屬性的值方法 
        String userName = request.getParameter("userName");
        String pwd = request.getParameter("pwd");
        String sex = request.getParameter("sex");
        String[] hobbys = request.getParameterValues("hobby");
        
        String city = request.getParameter("city");
        
        userName = new String(userName.getBytes("iso-8859-1"),"UTF-8");
        System.out.println(userName);
        System.out.println(pwd);
        System.out.println(sex);
        
        for (int i = 0;hobbys!=null && i < hobbys.length; i++) {
            System.out.print(hobbys[i]+"\t");
        }
        System.out.println();
        
        System.out.println(city);
測試一

   測試2使用方法:

     getParameterNames() 獲得表單提交的全部name的方法 

    getParameterValues(String name)專業爲複選框取取提供的方法

//獲取全部的表單name的名子
        Enumeration names = request.getParameterNames();
        while(names.hasMoreElements()){
            String name = (String) names.nextElement();//獲得每個name名
            String[] values = request.getParameterValues(name);//根據name名,獲得value值
            for (int i = 0;values!=null && i < values.length; i++) {
                System.out.println(name+"\t"+values[i]);
測試二    

   測試3使用方法:

    getParameterMap 到表單提交的全部值的方法   //作框架用,很是實用

try {
            User u = new User();
            System.out.println("封裝數據前:"+u);
            //獲取表單數據
            Map<String,String[]> map = request.getParameterMap();
            
            for (Map.Entry<String, String[]> m : map.entrySet()) {
                String name = m.getKey();
                String[] value = m.getValue();
                
                //建立一屬性描述器
                PropertyDescriptor pd = new PropertyDescriptor(name, User.class);
                //獲得setter屬性
                Method setter = pd.getWriteMethod();
                
                if(value.length==1){
                    setter.invoke(u, value[0]);//給一個值的變量賦值
                }else{
                    setter.invoke(u, (Object)value);//相關於給複選框賦值
                }
            }
            
            System.out.println("封裝數據後:"+u);
        } catch (Exception e) {
            e.printStackTrace();
        }
測試三

  測試4使用方法:

    getInputStream  以字節流的方式獲得全部表單數據

request.setCharacterEncoding("UTF-8");
        //獲取表單數據
        ServletInputStream sis = request.getInputStream();
        int len = 0;
        byte[] b = new byte[1024];
        while((len=sis.read(b))!=-1){
            //System.out.println(new String(new String(b,0,len).getBytes(),"utf-8"));
            System.out.println(new String(b, 0, len, "UTF-8"));
        }
        
        sis.close();
測試四

   2)與操做非表單數據相關的方法(request也是一個域對象)

  方法:

    void setAttribute(String name, Object value);
    Object getAttribute(String name);
    Void removeAttribute(String name);

  3)與請求轉發相關的方法

  方法: 

    //獲得請求轉發或請求包含的協助對象
    RequestDispatcher getRequestDispatcher(String path)
    forward(ServletRequest request, ServletResponse response) //轉發的方法
    include(ServletRequest request, ServletResponse response) //請求包含

  注意:    

    include()方法的處理流程:
      一是:若是目標組件爲Servlet或JSP,就執行它們,並把它們產生的響應正文添加到源組件的響應結果中;
      若是目標組件爲HTML文檔,就直接把文檔的內容添加到源組件的響應結果中。
      二是:返回到源組件的服務方法中,繼續執行後續代碼塊。
    特色:
      一是:源組件與被包含的目標組件的輸出數據都會被添加到響應結果中。
      二是:在目標組件中對響應狀態代碼或者響應頭所作的修改都會被忽略。

   使用:

    //path:轉發後跳轉的頁面,這裏無論用不用"/"開頭,都是以web項目根開始,由於這是請求轉發,請求轉發只侷限與在同一個web項目下使用,因此這裏一直都是從web項目根下開始的。 

    request.getRequestDispatcher(String path).forward(request,response);     

    web項目根:

      開發:G:\Workspaces\test01\WebRoot\..

      運行時:D:\java\tomcat\apache-tomcat-7.0.53\webapps\test01\..

    web站點根:

      運行時:D:\java\tomcat\apache-tomcat-7.0.53\webapps\..

     從這裏能夠看出,web項目根就是從該web項目名開始,因此咱們請求轉發時,只須要接着項目名後面須要訪問的路徑寫就行了。

    特色:瀏覽器中url不會改變,也就是瀏覽器不知道服務器作了什麼,是服務器幫咱們跳轉頁面的,而且在轉發後的頁面,可以繼續使用原先的request,由於是原先的request,因此request域中的屬性均可以繼續獲取到。

  4)與編碼相關的方法  

    //解決post方式編碼
      request.setCharacterEncoding("UTF-8"); //告訴服務器客戶端什麼編碼,只能處理post請求方式 
    //解決get方式編碼
      String name = new String(name.getBytes(「iso-8859-1」),」UTF-8」);

3、reqeust的常見應用

3.一、各類表單輸入項數據的獲取

  text、password、radio、checkbox、file、select、textarea、 hidden
  image、button給js編程用
  請求參數的中文亂碼問題 
  瀏覽器是什麼編碼就以什麼編碼傳送數據 
  解決:request.setCharacterEncoding(「UTF-8」);//POST有效
        new String(username.getBytes(「ISO-8859-1」),「UTF-8」);//GET方式

3.二、request對象實現請求轉發

  請求轉發指一個web資源收到客戶端請求後,通知服務器去調用另一個web資源進行處理
  request對象提供了一個getRequestDispatcher方法,該方法返回一個RequestDispatcher對象,調用這個對象的forward方法能夠實現請求轉發。
  request對象同時也是一個域對象,開發人員經過request對象在實現轉發時,把數據經過request對象帶給其它web資源處理

4、HttpServletResponse概述

4.一、HttpServletResponse簡介

  Web服務器收到客戶端的http請求,會針對每一次請求,分別建立一個用於表明請求的request對象、和表明響應的response對象。
  request和response對象即然表明請求和響應,那咱們要獲取客戶機提交過來的數據,只須要找request對象就好了。要向容器輸出數據,只須要找response對象就好了。
  HttpServletResponse對象表明服務器的響應。這個對象中封裝了向客戶端發送數據、發送響應頭,發送響應狀態碼的方法。
  

4.二、HttpServletResponse細節  

  getOutputStream和getWriter方法分別用於獲得輸出二進制數據、輸出文本數據的ServletOuputStream、Printwriter對象。

  getOutputStream和getWriter這兩個方法互相排斥,調用了其中的任何一個方法後,就不能再調用另外一方法。 會拋異常。

  Servlet程序向ServletOutputStream或PrintWriter對象中寫入的數據將被Servlet引擎從response裏面獲取,Servlet引擎將這些數據看成響應消息的正文,
  而後再與響應狀態行和各響應頭組合後輸出到客戶端。

  Serlvet的service方法結束後,Servlet引擎將檢查getWriter或getOutputStream方法返回的輸出流對象是否已經調用過close方法,
  若是沒有,Servlet引擎將調用close方法關閉該輸出流對象。

5、詳解HttpServletResponse

5.一、響應行

  響應狀態行    HTTP/1.1  200 OK

  常見的響應狀態碼:    

  200 OK
    一切正常,對GET和POST請求的應答文檔跟在後面
  3XX  用於已經移動的文件而且充被包含在定位頭信息中指定新的地址消息
    302 Found
    相似於301,但新的URL應該被視爲臨時性的替代,而不是永久性的。
  4XX  用於指出客戶端的錯誤
    404 Not Found  沒法找到指定位置的資源 
  5XX   用於支持服務器錯誤
    500 Internal Server Error   服務器遇到了意料不到的狀況,不能完成客戶的請求
  方法:
    setStatus(int sc) 設置響應狀態碼

5.二、響應頭

  常見的響應頭  
        Accept:指示HTTP響應能夠接收的文檔類型集
        Accept-Charset:告知客戶能夠接收的字符集
        Accept-Encoding:全部響應的字符編碼集
        Content-Type:響應體的MIME類型
        Content-Language:響應體的語言類型
        Content-Length:響應體的長度和字節數
        Expires:通知客戶端過時時間,防止客戶瀏覽器使用本地緩存副本
        Cookie:包含保存到客戶端的Cookie集
        Redirect:提供指定重定向,能夠不向瀏覽器輸出響應內容,而是直接從新請求到另外一個URL地址,實現重定向響應,便是一種自動定向。 
  方法:
    setHeader(String name, String value) 設置響應頭信息
    舉例:
      response.setHeader(java.lang.String name, java.lang.String value) 設置指定的頭,通常經常使用。 
    //告知瀏覽器使用什麼碼錶
    response.setHeader("content-type", "text/html;charset=UTF-8");
    代替了:
      //告訴服務器應用使用UTF-8解析文本
        response.setCharacterEncoding("UTF-8");
        //告訴客戶端要使用什麼編碼
        response.setHeader("content-type", "text/html;charset=UTF-8");
      
      
       //告知客戶端不緩存
      response.setHeader("pragma", "no-cache");
      response.setHeader("cache-control", "no-cache");
      response.setDateHeader("expires", 0);
 
      //設置每隔3秒就自動刷新一次
      response.setHeader("Refresh",3);

5.三、響應正文

  經常使用方法:

    getWrite(); 字符輸出流
    getOutputStream(); 字節輸出流
    setCharacterEncoding(String charset) 告知服務器使用什麼編碼
    setContentType(String type)

 5.四、重定向

  1)重定向運行原理  

    重定向機制的運做流程
    第一步:用戶在瀏覽器端輸入特定URL,請求訪問服務器端的某個組件
    第二步:服務器端的組件返回一個狀態碼爲302的響應結果。
    第三步:當瀏覽器端接收到這種響應結果後,再當即自動請求訪問另外一個web組件
    第四步:瀏覽器端接收到來自另外一個web組件的響應結果。
    HttpServeltResponse的sendRedirect(String location)用於重定向

   2)具體實現

  方式一:手動方案

    response.setStatus(302);  //狀態碼302就表明重定向

    response.setHeader("location","http://www.baidu.com");

  方式二:使用封裝好的,經過response.sendRedirect("http://www.baidu.com");

    特色:服務器告訴瀏覽器要跳轉的頁面,是瀏覽器主動去跳轉的頁面,瀏覽器知道,也瀏覽器的地址欄中url會變,是瀏覽器從新發起一個請求到另一個頁面,因此request是從新發起的,跟請求轉發不同

    注意:response.sendRedirect(path);  //

    第一種:response.sendRedirect("/test01/MyServlet01");  //使用了"/"開頭,說明是從web站點根開始,因此須要寫test01/MyServlet01

    第二種:response.sendRedirect("MyServlet01");  //沒有使用"/"開頭,說明是從web項目根開始,那麼就無需寫test01了

    注意:重定向沒有任何侷限,能夠重定向web項目內的任何路徑,也能夠訪問別的web項目中的路徑,而且這裏就用"/"區分開來若是使用了"/"開頭,就說明我要從新開始定位了,不訪問剛纔的web項目,本身寫項目名,

       若是沒有使用"/"開始,那麼就知道是訪問剛纔那個web項目下的servlet,就能夠省略項目名了。就是這樣來區別。 

6、Response常見應用

6.一、向客戶端輸出中文數據

  1)用OutputStream(字節流)發送數據:
    response.getOutputStream().write(「中國」.getBytes());//以默認編碼發送數據
    response.getOutputStream().write("中國".getBytes("UTF-8"));//以UTF-8編碼發送數據,瀏覽器(默認用GB2312)會出現亂碼
 
  解決辦法:
    經過更改瀏覽器的編碼方式:IE/」查看」/」編碼」/」UTF-8」(不可取)
    經過設置響應頭告知客戶端編碼方式:response.setHeader(「Content-type」, 「text/html;charset=UTF-8」);//告知瀏覽器數據類型及編碼
    經過meta標籤模擬請求頭:out.write("<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />".getBytes());
    經過如下方法:response.setContentType("text/html;charset=UTF-8");
 
  2)用PrintWriter(字符流)發送數據:
    示例:response.getWriter().write(「中國」 );有沒有亂碼?
    緣由:以默認編碼發送數據 ISO-8859-1(沒有中國二字編碼),此時會發生亂碼
  解決辦法:
    setCharacterEncoding(「UTF-8」);
    //更改編碼爲UTF-8
    response.setHead(「Context-type」,」text/html;charset=UTF-8」);
    //告訴客戶端編碼方式
  注意:不要忘記告訴客戶端的編碼方式。
    因爲常常改動編碼,response提供了一種更簡單的方式
    response. setContentType(「text/html;charset=UTF-8」); 其做用至關於以上兩條代碼。

6.二、文件下載

//經過路徑獲得一個輸入流
        String path = this.getServletContext().getRealPath("/WEB-INF/classes/美女.jpg");
        FileInputStream fis = new FileInputStream(path);
        //建立字節輸出流
        ServletOutputStream sos = response.getOutputStream();
        
        //獲得要下載的文件名
        String filename = path.substring(path.lastIndexOf("\\")+1);
        
        //設置文件名的編碼
        filename = URLEncoder.encode(filename, "UTF-8");//將不安全的文件名改成UTF-8格式
        
        //告知客戶端要下載文件
        response.setHeader("content-disposition", "attachment;filename="+filename);
        response.setHeader("content-type", "image/jpeg");
        
        //執行輸出操做
        int len = 1;
        byte[] b = new byte[1024];
        while((len=fis.read(b))!=-1){
            sos.write(b,0,len);
        }
        
        sos.close();
        fis.close();
代碼示例

 6.三、生成驗證碼

  以後我會詳細介紹

6.四、定時刷新頁面

  利用Refresh刷新到其餘組件。模擬註冊頁面,註冊處理交由一個Servlet,在Servlet處理完成後,顯示註冊成功並轉向主頁。(meta也可實現)

  

 

喜歡就點個「推薦」哦!

相關文章
相關標籤/搜索