第5章 处理GET请求参数

1 什么是GET请求参数

        表单GET请求参数是指在HTML表单中通过GET方法提交表单数据时所附带的参数信息。在HTML表单中,可以通过表单元素的name属性来指定表单字段的名称,通过表单元素的value属性来指定表单字段的值。当用户提交表单时,浏览器会将表单字段的名称和值以键值对的形式打包成查询字符串(query string),将查询字符串附加到表单的action URL中作为GET请求的参数信息。

        例如,假设一个简单的表单如下所示:

  <h1>用户注册</h1>
  <form action="/accounts/register" >
    <label>姓名:<input type="text" name="name" placeholder="请输入您的姓名"></label><br>
    <label>密码:<input type="password" name="password" placeholder="请输入密码"></label><br>
    <label>邮箱:<input type="text" name="email" placeholder="请输入邮箱"></label><br>
    <label>性别:<input type="text" name="gender" placeholder="输入性别"></label><br>
    <input type="submit" value="提交">
  </form>

        其中,action属性指定表单提交的目标URL。当填写姓名为“Tom”,密码“1234”,邮箱“tom@demo.com”,性别“男”:

        并且点击"提交"按钮提交表单时,浏览器将发送一个GET请求到"http://localhost:8089/accounts/register "。

        在服务服务器端可以看到如下信息:

        显然请求参数信息包含在uri中。

        由于我们没有在服务端接收这些参数,并且没有进行适当的处理,所以客户端得到了404错误。

2 解析GET请求参数

        解析GET请求参数的过程主要涉及对查询字符串进行解析和处理。通常,服务器端的程序可以通过以下步骤来解析GET请求参数:

        1. 获取URL中的查询字符串部分:对于HTTP GET请求,查询字符串部分位于URL中的问号字符(?)之后,可以通过解析URI来获取该部分的内容。

        2. 解析查询字符串中的键值对:查询字符串中的键值对通常使用等号(=)连接,键值对之间使用和号(&)连接。可以通过字符串分割和循环遍历来解析键值对。

        3. 对键值对的值进行解码:由于URL中的查询字符串部分需要进行URL编码以确保参数值的正确性和安全性,因此在解析时需要对键值对的值进行解码。

        综合上述步骤,我们可以使用Java代码实现GET请求参数的解析。解析过程如下所示:

3 解析GET请求参数的方法

        首先,添加解析请求参数的方法。

        解析请求功能显然是HttpServletRequest对象的职责,重构HttpServletRequest对象,添加解析请求参数的方法:

/** 查询字符串 */
private String queryString;
/** 请求路径 */
private String requestURI;
/** 存储全部参数 */
private HashMap<String, String> parameters = new HashMap<>();
private void parseUri(){
    //使用?拆分请求路径和查询字符串. ?是正则特殊字符,需要使用转义字符
    String[] parts = uri.split("\\?");
    requestURI = parts[0];
    queryString = parts[1];
    //使用&拆分解析查询字符串
    parts = queryString.split("&");
    for (String part : parts) {
        //使用 = 拆分出 name 和 value
        String[] param = part.split("=");
        String name = param[0];
        String value = param[1];
        parameters.put(name, value);
    }
    System.out.println("解析了参数:"+parameters);
}

        在这个解析方法中,假设请求 URI 为 /accounts/register?name=Tom&password=1234&email=tom%40demo.com&gender=%E7%94%B7,解析代码将分解成以下步骤达成目的:

        1、使用 split() 方法将 URI 拆分成两个部分,即请求路径和查询字符串。由于 ? 是一个正则特殊字符,因此需要使用转义字符 \\? 进行拆分。因此,parts 数组中将包含 "/accounts/register" 和 " name=Tom&password=1234&email=tom%40demo.com&gender=%E7%94%B7" 两个元素。

        2、将parts第一个元素存储到 requestURI 变量中。

        3、将parts第二个元素存储到 queryString 变量中。

        4、使用 split() 方法将查询字符串 queryString 拆分成多个参数。在这个示例中,使用 & 进行拆分,将得到一个包含四个元素的 parts 数组,分别是 "name=Tom"、" password=1234"、“email=tom%40demo.com”和gender=%E7%94%B7。

        5、对于每个参数,使用 split() 方法将参数名称和参数值拆分开。在这个示例中,使用 = 进行拆分。

        6、将每个参数名称和参数值存储到 parameters HashMap 中。

        7、输出map集合,检查解析是否成功了。

        然后,重构解析请求行方法 parseRequestLine:在uri中有?时候调用parseUri()方法对uri中的参数进行进一步的解析:

//解析请求行中的请求参数
if (uri.contains("?")){
    parseUri();
}else{
    requestURI = uri;
}

4 GET请求编码问题

        上述解析URL功能,接收到的中文和特殊字符会出现“乱码”,这个问题并不是乱码,而是HTTP协议通过URL传输数据时候,对特殊字符(中文)进行了编码。

        URL参数需要进行编码,是因为URL中只能包含特定的字符集,如字母、数字和一些特殊字符(中文),其他字符如果直接包含在URL中可能会导致URL无法正确解析或者出现意外的结果。因此,为了避免这种情况发生,需要对URL参数进行编码,以便在传输过程中对其进行安全的转换和传递。

        URL编码(也称百分号编码或URL转义):将URL参数中的非法字符转换成%xx的形式,其中xx是表示字符ASCII码值的16进制数字,例如空格的ASCII码值是32,因此用%20来表示空格。

        下面是一个URL参数编码的示例,假设要传递参数"Hello, World!",使用URL编码后的结果为:"Hello%2C%20World%21"。浏览器在发送数据时候,对数据进行了URL编码,服务端收到的就是这些“乱码”,只要进行对应的解码即可。

5 使用Java API对URL编码数据进行解码

        URL解码是将经过编码后的URL参数还原成原始数据的过程。URL解码的目的是为了恢复URL参数的原始含义,使得URL能够正确地被服务器解析和处理。

        URL解码(也称百分号解码或URL反转义):将URL参数中的%xx还原成对应的ASCII字符。例如,%20表示空格,将其解码后得到空格字符。

        Java API 提供了URLDecoder.decode()方法,对URL编码的数据进行解码:

  • 第一个参数为需要解码的URL参数
  • 第二个参数为字符编码方式:通常使用UTF-8
  • 输出解码后的结果

        下面是一个使用Java API对URL编码数据进行解码的示例,假设需要解码的URL参数为"Hello%2C%20World%21":

import java.net.URLDecoder;

public class URLDecoderExample {
   public static void main(String[] args) {
      try {
         String encodedURL = "Hello%2C%20World%21";
         String decodedURL = URLDecoder.decode(encodedURL, "UTF-8");
         System.out.println("Encoded URL: " + encodedURL);
         System.out.println("Decoded URL: " + decodedURL);
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

        输出结果为:

Encoded URL: Hello%2C%20World%21

Decoded URL: Hello, World!

        在示例中,首先使用URLDecoder.decode()方法对URL编码的数据进行解码。该方法的第一个参数为需要解码的URL参数,第二个参数为字符编码方式,通常使用UTF-8,最后输出解码后的结果。

6 HttpServletRequest添加参数解码功能

        继续重构HttpServletRequest的parseUri方法,将收到的请求数据进行URL解码,这样就可以解决特殊字符以及中文参数解码问题。

        代码示意如下:

private void parseUri() throws UnsupportedEncodingException {
    //使用?拆分请求路径和查询字符串. ?是正则特殊字符,需要使用转义字符
    String[] parts = uri.split("\\?");
    requestURI = parts[0];
    queryString = parts[1];
    //使用&拆分解析查询字符串
    parts = queryString.split("&");
    for (String part : parts) {
        //使用 = 拆分出 name 和 value
        String[] param = part.split("=");
        String name = param[0];
        String value = URLDecoder.decode(param[1], "UTF-8");
        parameters.put(name, value);
    }
    System.out.println("解析了参数:"+parameters);
}

        在对接收参数进行URL解码后,在表单中添入中文,在服务端就能接收到正确结果了:

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

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

相关文章

C# WinForm —— 16 MonthCalendar 介绍

1. 简介 可以选择单个日期&#xff0c;也可以选择一段日期&#xff0c;在选择时间范围上 比较适用&#xff0c;但不能跨月份选择日期范围 在直观上&#xff0c;可以快速查看、选择日期/日期范围 2. 常用属性 属性解释(Name)控件ID&#xff0c;在代码里引用的时候会用到,一般…

邮箱API发送邮件调试的方法?有哪些限制?

邮箱API发送邮件调试的好处&#xff1f;如何正确调试邮箱API&#xff1f; 使用邮箱API发送邮件是一个常见的需求。然而&#xff0c;当遇到发送失败、内容错误或格式问题时&#xff0c;如何进行有效的调试就显得尤为重要。本文将为您介绍一些邮箱API发送邮件调试的方法&#xf…

Leetcode-有效的括号

20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/valid-parentheses/ 题目 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&…

MySql软件安装

1.打开mysql官网网址 MySQL :: Download MySQL Community Server 2.本次针对版本8的图形化界面安装&#xff0c;下载成功后接下来对MySQL进行安装 3.图形化下载后有一个MSI文件 4.我们安装典型即可&#xff0c;选择第一个 5.选择数据库信息存放的路径&#xff0c;我默认放在C盘…

Redis继续(黑马)

Redis持久化 RDB与AOF RDB记录是二进制数据&#xff0c;Redis停机时会触发保存&#xff0c;名称&#xff1a; dump.rdb 缺点&#xff1a;间歇式复制可能存在宕机数据更新丢失 AOF 记录的写操作命令&#xff0c;每秒记录一下&#xff0c;也存在数据更新丢失的可能&#xff0c;相…

【数轮】数论、质数、最大公约数、菲蜀定理

数学 唯一分解定理 n>2都可以表示为质因数的乘方。 令 n a1b1a2b2 … \dots … a1,b1 … \dots …都是质因数&#xff0c;b1,b2 … \dots …是对应质因数的数量。 调和级数 11/2 1/3 1/4 ⋯ \cdots ⋯ 1/ n 约等于 logn。 证明过程&#xff1a; 1/3 1/4 < (1/2) …

idea已配置的git仓库地址 更换新的Git仓库地址 教程

文章目录 目录 文章目录 更改流程 小结 概要更改流程技术细节小结 概要 先在idea控制台走一下流程 先将本地的git仓库删除 1. 查看当前远程仓库地址&#xff1a; 在终端或命令行中&#xff0c;导航到你的项目目录&#xff0c;并运行以下命令查看当前的远程仓库地址&#xff…

CTF之love_math

这个题目简单看一下就知道要传参进行执行系统命令以达到找到flag的目的。 但是又可以发现过滤了很多东西。 这个题的绕过方法可以用到三个函数 base_convert(number,froombase,tobase)//分别为原始值&#xff0c;原来进制&#xff0c;要转换的进制dechex("十进制数"…

气膜建筑电源配置是怎样的—轻空间

在气膜建筑中&#xff0c;电源配置是确保建筑控制系统连续运行的重要组成部分。以下是该建筑的电源配置方案&#xff1a; 1. 市电供电与备用发电机&#xff1a; 为了应对市电中断等突发情况&#xff0c;系统采用市电供电与备用柴油发电机双重供电方式。这种配置保证了即使在市电…

JDK APT(Annotation Processing Tool) 编译时注解处理器

博文目录 文章目录 javacAnnotation ProcessingHow Annotation Processing WorksCompilation Environment and Runtime Environment maven-compile-plugin对 Maven pom 中配置注解处理器的理解Lombok, MapStruct, MyBatis-Flex 说明测试只在 dependencies 中配置 Lombok 和 Ma…

【网络安全】适合新手的CTF靶场合集(非常详细)零基础入门到精通,收藏这一篇就够了

前言 经常会有粉丝朋友询问大白&#xff0c;如何打CTF比赛&#xff0c;有没有适合新手的CTF靶场&#xff1f; 今天呢大白就给粉丝朋友分享一下&#xff0c;我整理得可能没有那么全&#xff0c;这里的合集主要还是面对新手。做题贵精不在多&#xff0c;好好练习每一题&#xf…

STM32 PWM 计数器模式和对齐

STM32 PWM 计数器模式和对齐 1. TIM高级定时器简介2. TIM计数模式2.1 向上计数2.2 向下计数2.3 中心对齐模式&#xff08;向上/向下计数&#xff09;2.4 重复计数 3. PWM输出模式3.1 举例看下PWM中心对齐模式&#xff0c;设置参数如下&#xff1a; 4. FOC中PWM相关设置说明4.1 …

其他的 框架安全:Apache Shiro 漏洞序列.(CVE-2016-2807)

什么是 Apache Shiro Apache Shiro 是一个强大且易用的Java安全框架&#xff0c;它为应用程序提供了身份验证、授权、加密和会话管理等常见的安全功能。漏洞大多会发生在登录处&#xff0c;返回包里包含remeberMedeleteMe字段.&#xff08; Shiro 这个属于第三方的&#xff0c…

Linux线程(三)死锁与线程同步

目录 一、什么是死锁 死锁的四个必要条件 如何避免死锁 避免死锁算法 二、Linux线程同步 三 、条件变量 1、条件变量基本原理 2、条件变量的使用 3、条件变量使用示例 为什么 pthread_cond_wait 需要互斥量? 一、什么是死锁 死锁是计算机科学中的一个概念&#xff0c;…

Qt---绘图和绘图设备

一、QPainter绘图 绘图事件 void paintEvent() 声明一个画家对象&#xff0c;OPainter painter(this) this指定绘图设备 画线、画圆、画矩形、画文字 设置画笔QPen 设置画笔宽度、风格 设置画刷QBrush 设置画刷风格 代码示例&#xff1a; #includ…

买一手股指期货跌多少会爆仓?

当指数下跌导致持有的股指期货合约价值减少&#xff0c;而你的保证金账户中的资金不足以维持原有的保证金要求时&#xff0c;期货公司会要求你追加保证金&#xff0c;即所谓的“追加保证金通知”。如果投资者无法及时补足保证金&#xff0c;期货公司则有权强制平仓&#xff0c;…

【Linux】磁盘文件

思维导图 学习目标 了解磁盘的物理结构和存储结构&#xff0c;并将其存储结构进行抽象&#xff01;&#xff01; 一、了解一下磁盘及其物理结构 1.1 计算机只认识二进制 什么是二进制&#xff1f;&#xff1f;0&#xff0c;1是被规定出来的&#xff0c;在计算机里面我们用高低…

SAP 控制已转采购订单的PR不允许删除简介

SAP系统中采购申请当被转成采购订单后&#xff0c;在采购申请中会关联到对应已生生成的采购订单&#xff0c;如下图中可以看到采购申请对应的采购订单 当日常操作中用户在创建完采购申请后&#xff0c;当PR转成PO后仍然可以将采购申请的行项目进行删除&#xff0c;显然这个操作…

『拼多多、淘宝、抖音、小红书等卖家』4个有效动作,走出成单低谷期

对于拼多多、淘宝、抖音、小红书等平台的卖家来说&#xff0c;走出成单低谷期需要一系列有效的动作。以下是店雷达四个建议&#xff1a; 一、选品优化 1、深入市场研究&#xff1a;了解当前市场趋势、消费者需求和潜在的市场空白。使用各种工具&#xff0c;如店雷达选品功能&…

Python深度学习基于Tensorflow(2)Tensorflow基础

文章目录 基本操作数据转换和数据生成操作形状数据提取和保存变量Numpy和Tensorflow的比较 计算图静态图动态图自动图 自动微分使用Tensorflow 实现回归 首先是Tensorflow的安装&#xff0c;由于可能会出现版本冲突&#xff0c;最好在conda环境安装&#xff0c;同时&#xff0c…