• JavaWeb核心之Request和Response


    概述

    request:获取请求数据

    • 浏览器会发送HTTP请求到后台服务器[Tomcat]
    • HTTP的请求中会包含很多请求数据[请求行+请求头+请求体]
    • 后台服务器[Tomcat]会对HTTP请求中的数据进行解析并把解析结果存入到一个对象中
    • 所存入的对象即为request对象,所以我们可以从request对象中获取请求的相关参数
    • 获取到数据后就可以继续后续的业务,比如获取用户名和密码就可以实现登录操作的相关业务

    response:设置响应数据

    • 业务处理完后,后台就需要给前端返回业务处理的结果即响应数据
    • 把响应数据封装到response对象中
    • 后台服务器[Tomcat]会解析response对象,按照[响应行+响应头+响应体]格式拼接结果
    • 浏览器最终解析结果,把内容展示在浏览器给用户浏览

    Request

    request继承体系

    • 当我们的Servlet类实现的是Servlet接口的时候,service方法中的参数是ServletRequest和ServletResponse
    • 当我们的Servlet类继承的是HttpServlet类的时候,doGet和doPost方法中的参数就变成HttpServletRequest和HttpServletReponse

    ServletRequest Java提供的请求对象根接口

    HttpServletRequest Java提供的对Http协议封装的请求对象接口

    RequestFacade Tomcat定义的实现类

    我们将这个对象打印出来验证一下

    @WebServlet("/ServletDemo1")
    public class ServletDemo1 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println(request);
            //org.apache.catalina.connector.RequestFacade@70d82d10
            //HttpServletRequest是根接口,RequestFacade是实现类
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doGet(request, response);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    Request获取请求数据

    HTTP请求数据总共分为三部分内容,分别是请求行、请求头、请求体

    @WebServlet(value = "/req02")
    public class ServletDemo2 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //get请求 请求数据分为请求行和请求头
            //请求头分为三部分:请求方式、请求资源路径和http协议
            //请求头是key-value形式
            //将请求数据解析为request,所以我们要从request中获取数据
    
            //请求方式
            String method = request.getMethod();
            System.out.println("method = " + method);
    
            //项目名
            String contextPath = request.getContextPath();
            System.out.println("contextPath = " + contextPath);
    
            //URI(项目名+资源路径)
            String requestURI = request.getRequestURI();
            System.out.println("requestURI = " + requestURI);
    
            //URL(统一资源标识符)
            StringBuffer requestURL = request.getRequestURL();
            System.out.println("requestURL = " + requestURL);
    
            //获取请求参数
            String queryString = request.getQueryString();
            System.out.println("queryString = " + queryString);
    
            //因为是key-value形式的,所以用key获取值
            String useragent = request.getHeader("user-agent");
            System.out.println("useragent = " + useragent);
    
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //post请求
            //doGet(request, response);
            //因为post请求的请求参数在请求体的最后一行(注意是一行)
            //我们要先获取流来取得参数
            //这个流不用自己关
            BufferedReader reader = request.getReader();
            String s = reader.readLine();
            System.out.println("s = " + s);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    获取请求参数的通用方式

    上面介绍了获取请求数据的方式,但是get和Post他们的请求参数放的位置不一致,(如果是GET请求,请求参数在请求行中; 如果是POST请求,请求参数一般在请求体中)所以分开来获取,但是太过于麻烦,我们可以用通用的方式获取请求参数。

    @WebServlet(value = "/req03")
    public class ServletDemo3 extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //get请求
            //get和post请求只有获取请求参数有不一致的地方,所以要分开,分为doGet和doPost
            //为了统一doGet和doPost,有了新的获取请求参数的方式,将username=zhangsan这种形式转为key-value,值多个时,用String数组
    
            //中文乱码问题
            //在tomcat8之后,get请求是支持中文,但是post不支持
            //所以要将post的编码方式改为utf8
            //因为doGet和doPost要统一,所以在doGet中判断一下请求方式,如果是post则进行修改
            String method = request.getMethod();
            if("post".equalsIgnoreCase(method)){
                request.setCharacterEncoding("utf8");//utf8、utf-8和UTF-8是一样的
            }
    
            //1.获取单个值
            String username = request.getParameter("username");
            System.out.println("username = " + username);
    
            //2.获取多个值
            String[] values = request.getParameterValues("hobby");
            System.out.println(Arrays.toString(values));
    
            //3.获取所有的map
            Map<String, String[]> map = request.getParameterMap();
            map.forEach((key,value)->{
                System.out.println(key+"::"+Arrays.toString(value));
            });
    
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //post请求
            System.out.println("post请求");
            doGet(request, response);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    Request请求转发

    请求转发(forward):一种在服务器内部的资源跳转方式。

    请求转发的特点:

    浏览器地址栏路径不发生变化

    只能转发服务器内部的资源,不能转发外部资源

    一次请求,可以在多个资源使用request共享资源

    AServlet

    @WebServlet(value = "/a")
    public class AServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //get请求
            //请求转发,只需要request就可以进行,好比说张三来向我节300块,我没有,我去向李四借,最后把借来的钱借给张三,张三并不知道我的钱是借的
            //请求转发的特点,浏览器地址栏路径不发生变化
            //只能转发服务器内部的资源,不能转发外部资源
            //一次请求,可以在多个资源使用request共享资源
            //getRequestDispatcher()中填写转发的路径(不用带"/")
            //forward(request,response) 将request,response这两个参数传递
            System.out.println("a资源");
            request.setAttribute("name","zhangsan");
            request.getRequestDispatcher("b").forward(request,response);
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //post请求
            doGet(request, response);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    BServlet

    @WebServlet(value = "/b")
    public class BServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //get请求
            System.out.println("b资源");
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //post请求
            doGet(request, response);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    Response对象

    Response继承体系

    ServletResponse Java提供的请求对象根接口

    HttpServletResponse Java提供的对Http协议封装的请求对象接口

    ResponseFacade Tomcat定义的实现类

    Response设置响应数据

    响应数据分为:响应行、响应头和响应体

    @WebServlet(value = "/ServletDemo4")
    public class
    ServletDemo4 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //get请求
            //response用来返回数据,结构层次:ServletResponse接口->HttpServletResponse接口->ResponseFacade实现类
    
            //设置响应行
            response.setStatus(404,"haha");
    
            //设置响应头
            //可以随意设置响应头的内容,但是不被认可,没有意义
            response.setHeader("ppp","666");
            response.setHeader("content-type","text/html");
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //post请求
            doGet(request, response);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    @WebServlet(value = "/ServletDemo5")
    public class ServletDemo5 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //get请求
            //设置乱码:两步:1.设置响应类型为text/html,2.设置html文本编码方式为utf8  charset=utf-8 中间用;隔开
            //注意设置中文一般放在第一步
            response.setContentType("text/html;charset=utf-8");
            //请求体
            PrintWriter writer = response.getWriter();
            //可以响应数据了
            writer.write("hellohellohello");
    
            //响应中文(出现乱码)
            writer.write("你好");
    
            //响应html
            writer.write("

    你好

    "
    ); //响应js writer.write(""); //我们不需要关闭PrintWriter流,因为response会为我们关闭,是他调用的,所以他来关闭,谁的事情谁来干 } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //post请求 doGet(request, response); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    Response重定向

    特点:

    浏览器地址路径会发生变化

    可以重定向到任意位置的资源(内部,外部均可)

    两次请求,不能共享数据

    CServlet

    @WebServlet(value = "/c")
    public class CServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //get请求
            //重定向 好比说张三微信来问我借300块,我没有,我告诉他说李四有,并给了他李四的地址
            //浏览器地址路径会发生变化
            //可以重定向到任意位置的资源(内部,外部均可)
            //两次请求,不能共享数据
            System.out.println("c资源");
            //sendRedirect(); ()里写资源路径,不用写"/"
            // 因为涉及到相对路径和绝对路径
            //在浏览器中: /开头是绝对路径,从localhost:端口号开始,会缺少项目访问路径
            //  没有”/“是相对路径,用当前路径作为参照,只会改变最后的路径名,不会缺少项目访问路径
            //浏览器使用时不加"/"
            //服务端使用时:
            //请求转发:加不加都可以
            //重定向:不加"/"     为了方便,我们浏览器和服务器都不加
            response.sendRedirect("d");
    
            //重定向到外部
            //response.sendRedirect("http://www.baidu.com");
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //post请求
            doGet(request, response);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    DServlet

    @WebServlet(value = "/d")
    public class DServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //get请求
            System.out.println("d资源");
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //post请求
            doGet(request, response);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    Response响应字节数据

    @WebServlet(value = "/ServletDemo6")
    public class ServletDemo6 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //get请求
            //字节输出流
            ServletOutputStream outputStream = response.getOutputStream();
            InputStream inputStream = new FileInputStream("src\\main\\webapp\\imgs\\reg_bg_min.jpg");
            /*
            这一步太麻烦,我们可以导入commons-io来使用工具类
            byte[] bytes = new byte[1024 * 8];
            int len;
            while ((len=inputStream.read(bytes))!=-1){
                outputStream.write(bytes,0,len);
            }*/
            //outputStream是response打开的,我们不管,我们开了inputStream,由我们来关闭
            //工具类
            IOUtils.copy(inputStream,outputStream);
            inputStream.close();
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //post请求
            doGet(request, response);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    最后

    如果你对本文有疑问,你可以在文章下方对我留言,敬请指正,对于每个留言我都会认真查看。

  • 相关阅读:
    Python requests爬虫豆瓣图片返回数据为空。
    Java基础 - 重写(Override)与重载(Overload)
    ByteHouse MaterializedMySQL 增强优化
    ES BulkRequest 写入索引数据失败排查和解决
    猿创征文 | 详解二叉树之遍历及其应用(动图遍历演示)
    记录使用layui弹窗实现签名、签字
    【leetcode】【剑指offer Ⅱ】039. 直方图最大矩形面积
    Phala与Moonbeam集成,将PHA带入网络
    Docker Register 搭建私有镜像仓库
    JS移动端事件
  • 原文地址:https://blog.csdn.net/weixin_47543906/article/details/128165371