JavaWeb Request:获取请求数据

Request是请求对象,Response是响应对象。

在这里插入图片描述

浏览器会发送HTTP请求到后台服务器[Tomcat],请求中会包含很多请求数据 [请求行+请求头+请求体] ,后台服务器[Tomcat]会对HTTP请求中的数据进行解析并把解析结果存入到Request对象,可以从Request对象中获取请求的相关参数。

继承体系

在这里插入图片描述

因为ServletRequest和HttpServletRequest都是接口,无法直接创建对象,所以Tomcat的实现类通过解析并创建对象后,向上转型为接口类型以供使用。

通过debug可以看到ServletRequest的运行类型其实就是RequestFacade,而Response同理。

在这里插入图片描述

常用方法

获取请求行数据

在这里插入图片描述

  • String getMethod():获取请求方式,例:GET
  • String getContextPath():获取虚拟目录(项目访问路径),例:/request-demo
  • StringBuffer getRequestURL():获取URL(统一资源定位符),例: http://localhost:8080/request-demo/req1
  • String getRequestURI():获取URI(统一资源标识符),例: /request-demo/req1
  • String getQueryString():获取请求参数(GET方式),例: username=zhangsan&password=123

URL:统一资源定位符,例:http://localhost/arbor/demo1 中华人民共和国
URI:统一资源标识符,例:/arbor/demo1 共和国

@WebServlet("/req1")
public class RequestDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // String getMethod():获取请求方式: GET
        String method = req.getMethod();

        // String getContextPath():获取虚拟目录(项目访问路径):/request-demo
        String contextPath = req.getContextPath();

        // StringBuffer getRequestURL(): 获取URL(统一资源定位符):http://localhost:8080/request-demo/req1
        StringBuffer url = req.getRequestURL();

        // String getRequestURI():获取URI(统一资源标识符): /request-demo/req1
        String uri = req.getRequestURI();

        // String getQueryString():获取请求参数(GET方式): username=zhangsan
        String queryString = req.getQueryString();
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

获取请求头数据

请求头的数据格式为key: value

在这里插入图片描述

  • String getHeader(String name):所以根据请求头名称获取对应值
@WebServlet("/req1")
public class RequestDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求头: user-agent: 浏览器的版本信息
        String agent = req.getHeader("user-agent");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

获取请求体数据

浏览器在发送GET请求的时候是没有请求体的,所以请求方式为POST时获取请求体。

在这里插入图片描述

  • InputStream getInputStream():获取字节输入流,如果前端发送的是字节数据,比如传递的是文件数据,则使用该方法。
  • BufferedReader getReader():获取字符输入流,如果前端发送的是纯文本数据,则使用该方法。

BufferedReader流是通过request对象来获取的,当请求完成后request对象就会被销毁,request对象被销毁后,BufferedReader流就会自动关闭,所以不需要手动关闭流。

@WebServlet("/req1")
public class RequestDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         //获取post 请求体:请求参数
        //1. 获取字符输入流
        BufferedReader br = req.getReader();
        //2. 读取数据
        String line = br.readLine();
    }
}

【通用】获取请求参数

  • Map<String,String[]> getParameterMap():获取所有参数Map集合。
  • String[] getParameterValues(String name):根据名称获取参数值(数组)。
  • String getParameter(String name):根据名称获取参数值(单个值)。
@WebServlet("/req2")
public class RequestDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //GET请求逻辑
        System.out.println("get....");
        //1. 获取所有参数的Map集合
        Map<String, String[]> map = req.getParameterMap();
        for (String key : map.keySet()) {
            // username:zhangsan lisi
            System.out.print(key+":");

            //获取值
            String[] values = map.get(key);
            for (String value : values) {
                System.out.print(value + " ");
            }

            System.out.println();
        }

        System.out.println("------------");
        // 2. 获取单个参数的数组值
        String[] hobbies = req.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }

        // 3. 获取单个参数的单个值
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username);
        System.out.println(password);
        
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

中文乱码问题

POST的请求参数是通过request的getReader()来获取流中的数据,而Tomcat在获取流的时候采用的编码是ISO-8859-1,ISO-8859-1编码是不支持中文的,所以会出现乱码。

可以通过request.setCharacterEncoding("UTF-8")设置编码,UTF-8也可以写成小写。

  • request.setCharacterEncoding(String encode):设置request处理流的编码。
@WebServlet("/req4")
public class RequestDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        //1. 解决乱码: POST getReader()
        //设置字符输入流的编码,设置的字符集要和页面保持一致
        request.setCharacterEncoding("UTF-8");
       //2. 获取username
       String username = request.getParameter("username");
       System.out.println(username);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        this.doGet(request, response);
    }
}

Tomcat8已经将Get方式乱码问题解决了,而8以下的版本需要解决:

GET请求获取请求参数的方式是request.getQueryString()request.setCharacterEncoding("utf-8")是设置request处理流的编码。而getQueryString方法并没有通过流的方式获取数据,所以GET请求不能用设置编码的方式来解决中文乱码问题。

在这里插入图片描述

乱码原因:

  1. 浏览器通过HTTP协议发送请求和数据给后台服务器(Tomcat)
  2. 浏览器在发送HTTP的过程中会对中文数据进行URL编码
  3. 在进行URL编码的时候会采用页面<meta>标签指定的UTF-8的方式进行编码,张三编码后的结果为%E5%BC%A0%E4%B8%89
  4. 后台服务器(Tomcat)接收到%E5%BC%A0%E4%B8%89后会默认按照ISO-8859-1进行URL解码
  5. 由于前后编码与解码采用的格式不一样,就会导致后台获取到的数据为乱码。

解决方式:

@WebServlet("/req4")
public class RequestDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        //1. 解决乱码:POST,getReader()
        //request.setCharacterEncoding("UTF-8");//设置字符输入流的编码

        //2. 获取username
        String username = request.getParameter("username");
        System.out.println("解决乱码前:"+username);

        //3. GET,获取参数的方式:getQueryString
        // 乱码原因:tomcat进行URL解码,默认的字符集ISO-8859-1
       /* //3.1 先对乱码数据进行编码:转为字节数组
        byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
        //3.2 字节数组解码
        username = new String(bytes, StandardCharsets.UTF_8);*/
        username  = new String(username.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
        System.out.println("解决乱码后:"+username);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        this.doGet(request, response);
    }
}

请求转发

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

转发的特点:

  • 浏览器地址栏路径不发生变化
  • 只能转发到当前服务器的内部资源
  • 一次请求,可以在转发资源间使用request共享数据

转发的流程:

  1. 浏览器发送请求给服务器,服务器中对应的资源A接收到请求
  2. 资源A处理完请求后将请求发给资源B
  3. 资源B处理完后将结果响应给浏览器
  4. 请求从资源A到资源B的过程就叫请求转发

在这里插入图片描述

请求转发的实现方式:

req.getRequestDispatcher("资源B路径").forward(req, resp);

而转发时,可以设置数据共享和传输,Request中有三个方法:

常用方法

  • RequestDispatcher getRequestDispatcher(String path):通过request对象获取请求转发器对象。

  • forward(ServletRequest request, ServletResponse response):使用RequestDispatcher对象来进行转发

  • void setAttribute(String name, Object o):存储数据到request域[范围,数据是存储在request对象]中。

  • Object getAttribute(String name):根据key获取值。

  • void removeAttribute(String name):根据key删除该键值对。

域对象:一个有作用范围的对象,可以在范围内共享数据

request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据

  • ServletContext getServletContext():获取ServletContext。
@WebServlet("/req5")
public class RequestDemo5 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        System.out.println("demo5...");
        //存储数据
        request.setAttribute("msg","hello");
        //请求转发
        request.getRequestDispatcher("/req6").forward(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        this.doGet(request, response);
    }
}
@WebServlet("/req6")
public class RequestDemo6 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
        System.out.println("demo6...");
        //获取数据
        Object msg = request.getAttribute("msg");
        System.out.println(msg);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        this.doGet(request, response);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/430177.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Docker之数据卷

目录 一、什么是数据卷 二、自定义镜像 一、什么是数据卷 1.1Docker 数据管理 在生产环境中使用 Docker &#xff0c;往往需要对数据进行持久化&#xff0c;或者需要在多个容器之间进行 数据共享&#xff0c;这必然涉及容器的数据管理操作 二、操作 将宿主机的目录与容器的…

双通道音频功率放大电路,外接元件少, 通道分离性好,3V 的低压下可正常使用——D2025

D2025 为立体声音频功率放大集成电路&#xff0c;适用于各类袖珍或便携式立体声 收录机中作功率放放大器。 D2025 采用 DIP16 封装形式。 主要特点&#xff1a;  适用于立体声或 BTL 工作模式  外接元件少  通道分离性好  电源电压范围宽&#xff08;3V~12V &#xff…

深度学习GPU环境安装(WINDOWS安装NVIDIA)

1.检测是否支持GPU环境 1.1.打开设备管理器 winows下面搜索设备管理器&#xff08;或者从桌面"此电脑"——>右键点击——>"管理"打开&#xff09; 1.2.查看本地显卡 在"设备管理器"——"显示适配器"中&#xff0c;如果没有&…

瑞吉外卖项目详细分析笔记及所有功能补充代码

目录 项目刨析简介技术栈项目介绍项目源码 一.架构搭建1.初始化项目结构2.数据库表结构设计3.项目基本配置信息添加公共字段的自动填充全局异常处理类返回结果封装的实体类 二.管理端业务开发1.员工管理相关业务1.1员工登录1.2员工退出1.3过滤器拦截1.4员工信息修改1.5员工信息…

ElasticSearch之分片相关概念segment,merge,refresh等

写在前面 本文看下分片相关概念&#xff0c;segment&#xff0c;merge&#xff0c;refresh等。 1&#xff1a;segment&#xff0c;commit point&#xff0c;.del 一个倒排索引的文件称为segment&#xff0c;多个segment组合在一起就是lucene的index&#xff0c;也就是es的sh…

线程变量ThreadLocal用于解决多线程并发时访问共享变量的问题。

ThreadLocal介绍 ThreadLocal叫做线程变量&#xff0c;用于解决多线程并发时访问共享变量的问题。意思是ThreadLocal中填充的变量属于当前线程&#xff0c;该变量对其他线程而言是隔离的&#xff0c;也就是说该变量是当前线程独有的变量。ThreadLocal为变量在每个线程中都创建…

12. Nginx进阶-Location

简介 Nginx的三大区块 在Nginx中主要配置包括三个区块&#xff0c;结构如下&#xff1a; http { #协议级别include /etc/nginx/mime.types;default_type application/octet-stream;log_format main $remote_addr - $remote_user [$time_local] "$r…

ssl证书无效是否继续访问啥意思

SSL证书&#xff08;Secure Sockets Layer&#xff09;是现代互联网通信安全的基础组成部分&#xff0c;尤其对于涉及敏感信息交换的HTTPS站点至关重要。当浏览器提示“SSL证书无效”时&#xff0c;这意味着浏览器无法验证网站的身份或确定其加密连接的安全性。这种情况下&…

基于Python+Flask实现一个TODO任务管理系统网站

随着科技的进步&#xff0c;数字化的任务清单逐渐成为生活中不可或缺的一部分。它们不仅可以帮助我们跟踪日常任务&#xff0c;还可以提高效率。但是&#xff0c;你是否考虑过自己制作一个任务管理系统呢&#xff1f; 好消息是&#xff0c;使用Python和Flask&#xff0c;我们可…

器件选型【MOS,三极管篇】

三极管篇&#xff1a; 三极管的两大作用&#xff1a;做开关使用和放大电流 一句话总结&#xff1a;三极管选型主要考虑集电极最大允许电流&#xff0c;集电极-发射极反向击穿电压&#xff0c;集电极最大允许耗散功率&#xff0c;特征频率&#xff0c;封装形式&#xff0c;工作…

电脑防火墙怎么关?分享2个简单方法

在当今数字化时代&#xff0c;保护计算机免受网络威胁和恶意软件攻击是至关重要的。电脑防火墙作为一种重要的安全措施&#xff0c;可以有效地阻止未经授权的网络访问&#xff0c;保障您的个人信息和数据安全。 然而&#xff0c;有时候在特定情况下&#xff0c;您可能需要临时…

【ES入门一:基础概念】

集群层面上的基础概念 集群 由多个es实例组成的叫做集群 节点 单个ES的服务实例叫做节点。每个实例都有自己的名字&#xff0c;就是在配置文件中配置的‘node.name’中的内容。为了标识每个节点&#xff0c;每个节点启动后都会分配一个UID&#xff0c;存储在data目录。每个…

【leetcode】三数之和 双指针

/*** param {number[]} nums* return {number[][]}*/ var threeSum function(nums) {nums.sort((a,b)>a-b);let result[];for(let i0;i<nums.length-2;i){if(nums[i]>0) return result;//因为求三数之和等于0&#xff0c;如果第一个数已经大于0&#xff0c;后面肯定无…

数仓实战——懂车帝数据指标体系建设和应用实践

目录 一、如何建立指标体系规范 1.1 懂车帝业务介绍 1.2 为什么要做指标体系规范 1.3 DataLeap 指标管理平台 1.4 指标体系建设框架 1.5 指标元数据管理规范 二、指标模型建设在数仓工作中的收敛 2.1 指标模型建设存在的问题 2.2 指标模型数仓层级建设标准 2.3 从指标…

stm32f103zet6笔记1-led工程

1、选择串口调试 2、LED0连接到PB5&#xff0c;PB5设置为推挽输出。PE5同理。 3、生成成对的.c,.h文件。 4、debugger选择j-link。 5、connection选择SWD。 6、编写bsp_led.c,bsp_led.h文件。 7、下载调试&#xff0c;可以看到LED0 500ms闪烁一次&#xff0c;LED1 1000ms闪烁一…

Node.js与Webpack笔记(一)

这里使用的16.19.0版本&#xff0c;官网和github没找到&#xff0c;去黑马2023年课程里找 篇幅较大会卡&#xff0c;此篇幅不写Webpack部分&#xff0c;留着下一篇 初识 1.什么是Node.js? Node.js 是一个独立的 JavaScript 运行环境&#xff0c;能独立执行 JS 代码&#xff…

基于机器学习的曲面拟合方法

随着科技的不断发展&#xff0c;机器学习成为了最近最热门的技术之一&#xff0c;也被广泛应用于各个领域。其中&#xff0c;基于机器学习的曲面拟合方法也备受研究者们的关注。曲面拟合是三维模型处理中的重要技术&#xff0c;其目的是用一组数据点拟合出平滑的曲面&#xff0…

STM32启动过程及反汇编

STM32从Flash启动的过程&#xff0c;主要是从上电复位到main函数的过程&#xff0c;主要有以下步骤&#xff1a; 1.初始化堆栈指针 SP_initial_sp&#xff0c;初始化 PC 指针Reset_Handler 2.初始化中断向量表 3.配置系统时钟 4.调用 C 库函数_main 初始化用户堆栈&#xf…

【软件测试】Postman中变量的使用

Postman中可设置的变量类型有全局变量&#xff0c;环境变量&#xff0c;集合变量&#xff0c;数据变量及局部变量。区别则是各变量作用域不同&#xff0c;全局变量适用于所有集合&#xff0c;环境变量适用于当前所选环境&#xff08;所有集合中均可使用不同环境变量&#xff09…

常用通讯协议的理解

一、通讯的一些基本认知 1、什么是异步或同步通信 异步通信在发送字符时&#xff0c;所发送的字符之间的时间间隔可以是任意的。发送端可以在任意时刻开始发送字符&#xff0c;因此必须在每一个字符的开始和结束的地方加上标志&#xff0c;即加上开始位和停止位&#xff0c;以…