8.Request

       1. request

              代表HTTP请求。

              a. HTTP请求由四部分组成:

                     请求行         get  请求资源名称   HTTP协议版本

                     多个请求头  

                     一个空行      

                     请求实体内容      请求参数

              b. 请求的继承结构

                     ServletRequest   

                            |

                             |----HttpServletRequest   在原有接口之上添加了HTTP协议相关的API,更善于HTTP协议相关开发。

       2. 请求的功能

              a. 获取请求资源

                     getRequestURL方法 -- 返回客户端发出请求完整URL

                     getRequestURI方法 -- 返回请求行中的资源名部分

                     getQueryString方法 -- 返回请求行中的参数部分

                     getRemoteAddr方法 -- 返回发出请求的客户机的IP地址

                     getMethod -- 得到客户机请求方式

                     !!getContextPath -- 获得当前web应用虚拟目录名称 -- 在写路径时不要将web应用的虚拟路径的名称写死, 应该在需要写web应用的名称的地方通过getContextPath方法动态获取

 

             

 

public class RequestDemo1 extends HttpServlet {

//    getRequestURL方法 -- 返回浏览器发出请求完整URL
//    getRequestURI方法 -- 返回请求行中的资源名部分
//    getQueryString方法 -- 返回请求行中的参数部分
//    getRemoteAddr方法 -- 返回发出请求的客户机的IP地址
//    getMethod -- 得到浏览器请求方式
//    !!getContextPath -- 获得当前web应用虚拟目录名称 -- 在写路径时不要将web应用的虚拟路径的名称写死, 应该在需要写web应用的名称的地方通过getContextPath方法动态获取

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //请求的URL 路径是http://localhost:8080/day08-servlet/servlet/RequestDemo1?username=xwq&password=123456
        StringBuffer url = request.getRequestURL();
        System.out.println("url:"+url.toString()); //url:http://localhost:8080/day08-servlet/servlet/RequestDemo1
        String uri = request.getRequestURI();
        System.out.println("uri:"+uri);    //uri:/day08-servlet/servlet/RequestDemo1
        String qs = request.getQueryString();
        System.out.println("qs:"+qs);//qs:username=xwq&password=123456
        String ip = request.getRemoteAddr();
        System.out.println("ip:"+ip);//ip:127.0.0.1
        String method = request.getMethod();
        System.out.println("method:"+method);//method:GET
        String cp = request.getContextPath();
        System.out.println("path:"+cp);//path:/day08-servlet     
    }

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

}

              b. 获取请求头

                     getHeader(name)方法 --- String

                     getHeaders(String name)方法 --- Enumeration<String>

                     getHeaderNames方法 --- Enumeration<String>

                     getIntHeader(name)方法  --- int   

                     getDateHeader(name)方法 --- long(日期对应毫秒)

             

//    getHeader(name)方法 --- String 
//    getHeaders(String name)方法 --- Enumeration<String>
//    getHeaderNames方法 --- Enumeration<String>
//    getIntHeader(name)方法  --- int
//    getDateHeader(name)方法 --- long(日期对应毫秒)

    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //根据请求头的名称获取对应值的操作
        String header = request.getHeader("Host");
        System.out.println("header:"+header);
        //根据请求头的名称获取对应值的操作--多个相同名称的请求头就好像多选框
        Enumeration<String> headers = request.getHeaders("host");
        while (headers.hasMoreElements()) {
            String name = headers.nextElement();
            System.out.println("name:"+name);
        }
        //获取全部请求头的名称
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String head = (String) headerNames.nextElement();//获取的请求头名称
            String value = request.getHeader(head); //根据请求头获取对应的值
            System.out.println("headername:"+head+">>value:"+value);
            
        }
           //如果指定的一个 头数据不能转化为整数,则抛出异常NumbereFormatException
        int intHeader = request.getIntHeader("");
        System.out.println(intHeader);
        //返回一个Unix时间戳(毫秒),如果头数据不能转化为日期,则抛出异常IllegalArgumentException
        long dateHeader = request.getDateHeader("");
        System.out.println(dateHeader);
        //获取请求内容的字符编码
        String characterEncoding = request.getCharacterEncoding();
        System.out.println(characterEncoding);

 

              c. 获取请求实体内容

                     getParameter(String name) --- String 通过name获得值

                     getParameterValues(String name)  --- String[ ] 通过name获得多值 checkbox

                     getParameterMap()  --- Map<String,String[ ]> key :name value: 多值  将查询的参数保存在一个Map中

                     getParameterNames()  --- Enumeration<String> 获得所有name

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //必须放在获取请求参数的代码之前,推荐放在所有代码之前。
        //通知服务器使用utf-8接收数据post请求有效。get请求无效
//        request.setCharacterEncoding("utf-8");
        //将?编码
        String username = request.getParameter("username");
        byte[] bytes = username.getBytes("iso8859-1");
        //再重新解码
        username = new String(bytes,"utf-8");
        System.out.println("username:"+username); //username:徐旺骑
        
        //getParameterValues  根据请求参数名获取一组请求参数值
        String[] likes = request.getParameterValues("like");
        System.out.println("likes:"+Arrays.toString(likes)); //likes:[lanqiu, zuqiu] 传过来的是多选框上面的values
        //getParameterMap 将所有请求参数获取到map中
        Map<String,String[]> map = request.getParameterMap();
        //getparameterNames  获取全部请求参数的名称
        Enumeration<String> names = request.getParameterNames();
        while (names.hasMoreElements()) {
            String name = (String) names.nextElement();
            String[] values = request.getParameterValues(name);
            System.out.println("name:"+name+"values:"+Arrays.toString(values));
        }
        
    }

 

                     i. 在获取请求参数时,如果获取中文数据,则会出现乱码。

                     ii. 乱码产生的原因:

                            编码和解码字符集不统一。

                     iii. 浏览器负责发送数据,在发送数据时会对数据编码,发送数据时所使用的字符集是页面加载时的字符集,为utf-8。

                     iv. 接收数据的是服务器,服务器在接收数据时会采用默认字符集iso8859-1解码数据。

                     v. 发送与接收字符集不同意,所以出现了乱码。由于iso8859-1中没有中文,所以应该将两者统一为utf-8。修改服务器的字符集。

                     vi. 如果是post提交,可以进行如下修改:

                            在所有获取请求参数的代码之前,书写:

                                   request.setCharacterEncoding("utf-8");

                            这句话仅能处理请求实体内容中的请求参数乱码,所以只对post请求有效。get请求无效。

                     vii. 如果是get请求,则需要在获取参数之后,先使用iso8859-1编码,在使用utf-8解码。

                            1) 代码如下:

                                   new String(username.getBytes("iso8859-1"),"utf-8");  //就是将url上获得的参数先转成二进制数据后将二进制数据在进行重新编码。

这种形式,既可以解决get提交的乱码,也可以解决post提交的乱码。

       3. request功能--请求转发

              请求转发是一种资源跳转方式,发生的服务器内部。

a 代码实现

            package cn.tedu.request;
            
            import java.io.IOException;
            
            import javax.servlet.RequestDispatcher;
            import javax.servlet.ServletException;
            import javax.servlet.http.HttpServlet;
            import javax.servlet.http.HttpServletRequest;
            import javax.servlet.http.HttpServletResponse;
            
            public class RequestDemo4 extends HttpServlet {
            
                    public void doGet(HttpServletRequest request, HttpServletResponse response)
                            throws ServletException, IOException {
                            //创建一个调度器
                            RequestDispatcher rd = request.getRequestDispatcher("/servlet/RequestDemo5");
                            //利用调度器实现请求转发
                            rd.forward(request, response);
                    }
            
                    public void doPost(HttpServletRequest request, HttpServletResponse response)
                            throws ServletException, IOException {
                            doGet(request, response);
            
                    }
            
            }

  b. 请求转发细节:

                     i. 请求转发之前如果向response缓冲区中写入数据,这些数据在请求转发是会被清空。

                     ii. 如果冲刷缓冲区,会造成一次响应,导致请求转发失败.所以不能冲刷缓冲区.

                     iii. 请求转发可以多重转发,但是不能在同一个servlet内多次请求转发.

                     iv. 在请求转发前后的代码也会正常执行.

                     v.在请求转发之前,如果response缓冲区中有数据,

                     则在请求转发的时候会将这些数据清空。

                    

多个请求转发会组成一个请求链,请求链的执行顺序是先执行所有请求转发之前的代码,在反向指向全部请求转发之后的代码.

4start 5start 6start  -> 6end 5end 4end

4. request功能--请求包含

      可以将两个servlet结果合并为一个结果输出.

      

public class RequestDemo8 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //请求包含
        response.getWriter().write("this is RequestDemo8");
        request.getRequestDispatcher("/servlet/RequestDemo9").include(request, response);
    }

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

    }

}

 

    5. request功能--作为域对象使用,上面的是requst请求对象

       a. 什么是域对象?

           i. 如果一个对象身上有一个可以被看见的范围,在这个范围内利用对象身上的map,实现数据的共享,这个对象就可以叫做域对象。

       b. 在域对象身上可以设有域属性,操作域属性的api如下:

           设置域属性:setAttribute(String name,Object obj);

           获取域属性:getAttribute(String name);

           删除域属性:removeAttribute(String name);

           获取全部域属性的名称:getAttributeNames();

           注意:

                  请求参数是Parameter,会随着form表单发送到服务器,通过getparameter()及其相关api获取.没有setparameter()

                  域属性是request对象作为域对象使用时,特有的属性。通过setAttribute设置,getAttribute获取。

                  域属性和请求参数是两个不同的数据,API不能混用。

       c. 练习:在servlet中设置域属性,在index.jsp页面获取域属性。

 

RequestDemo10.java
            package cn.tedu.request;
            
            import java.io.IOException;
            
            import javax.servlet.ServletException;
            import javax.servlet.http.HttpServlet;
            import javax.servlet.http.HttpServletRequest;
            import javax.servlet.http.HttpServletResponse;
            //request作为域对象使用
            public class RequestDemo10 extends HttpServlet {
            
                    public void doGet(HttpServletRequest request, HttpServletResponse response)
                            throws ServletException, IOException {
                            //在servlet中设置域属性
                            request.setAttribute("name", "曹洋");
                            request.setAttribute("age",18);
                            request.setAttribute("gender", "女");
                            request.setAttribute("wife", "丽丽");
                            //为了能够让当前servlet和index.jsp页面共享一个范围,需要实现请求转发
                            request.getRequestDispatcher("/index.jsp").forward(request, response);
                            
                    }
            
                    public void doPost(HttpServletRequest request, HttpServletResponse response)
                            throws ServletException, IOException {
                            doGet(request, response);
            
                    }
            
            }
         index.jsp:
            <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
            <!DOCTYPE HTML>
            <html>
              <head>
                
              </head>
              
              <body>
                   <h3>在index.jsp页面获取域属性</h3>
                   姓名:<%=request.getAttribute("name") %><br>
                   年龄:<%=request.getAttribute("age") %><br>
                   性别:<%=request.getAttribute("gender") %><br>
                   伴侣:<%=request.getAttribute("wife") %><br>
              </body>
            </html>

       d. 生命周期:

           当请求链开始的时候,request对象创建,

           当请求链结束的时候request对象销毁。

       e. 作用范围:

           整个请求链。

       f. 主要功能:

在整个请求链中共享数据。

posted @ 2019-08-12 10:11  三十六烦恼风x  阅读(338)  评论(0编辑  收藏  举报