• 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. 主要功能:

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

  • 相关阅读:
    [二叉树算法]关于层次遍历二叉树的一些算法总结
    数据库事务并发访问产生的问题及四种事务隔离级别
    当relative遇上z-index,阻断事件捕获
    关于CAS操作
    LRU算法与LRUCache
    Hadoop2.x 关于日志文件位置
    推荐系统架构图——我的软件工程概论课设
    文件上传+解析漏洞
    命令执行漏洞
    SSRF漏洞
  • 原文地址:https://www.cnblogs.com/xuwangqi/p/11338124.html
Copyright © 2020-2023  润新知