标准库网络密码学并发编程【免费下载链接】cangjie_stdx仓颉编程语言提供了 stdx 模块该模块提供了网络、安全等领域的通用能力。项目地址https://gitcode.com/Cangjie/cangjie_stdx点击查看免费下载本指南围绕stdx.encoding.url包中的Form类展开讲解如何从 URL 编码字符串构造表单对象、通过get/getAll读取键值映射、使用add/set/remove/clone修改内容以及用toEncodeString输出编码后的查询串。读完本文你将掌握在仓颉程序中处理 HTTP 表单参数与 URL query 组件的完整套路并理解其底层的解析与编码原理。背景URL 查询参数与表单的关系stdx.encoding.url包提供了 URL 相关能力解析 URL 各组件、编解码、合并 URL 或路径等详见 url 包总览。URL 的一般格式为scheme://host[:port]/path[?query][#fragment]其中query是查询参数部分例如?page2sortdesc由若干keyvalue键值对以分隔组成。HTTP 表单提交Content-Type: application/x-www-form-urlencoded时请求体也是同样的格式。Form类正是为这种场景设计的它以 key-value 键值对形式存储 HTTP 请求的表单/查询参数同一个 key 可以对应多个 valuevalue 以数组形式存储参见 Form 类定义。在介绍具体用法之前先了解 URL 编码百分号编码URL 只允许 ASCII 字符非 ASCII 字符需先转为 UTF-8 字节序列再逐字节写成%XX的十六进制形式。例如“你好世界”编码后为%E4%BD%A0%E5%A5%BD%EF%BC%8C%E4%B8%96%E7%95%8C%EF%BC%81。Form的构造与输出都围绕这套编码规则展开。一、Form 的两种构造方式Form提供两个公开构造函数public class Form { public init() public init(queryComponent: String) }1. 无参构造创建空表单Form()创建不包含任何键值对的空实例适合后续通过add/set逐步填充。源码实现是初始化一个空的HashMapString, ArrayListString见 form.cjimport stdx.encoding.url.* main() { // 使用无参构造函数创建 Form 实例 let form Form() }2. 带参构造从 URL 编码的查询字符串解析Form(queryComponent)接收 URL 的 query 组件字符串不含开头的?解析出若干键值对并填充到新实例中。解析规则见 form.cj 的实现先用分隔多个键值对自动忽略空段每个键值对再用切分左侧为 key右侧为 value没有或 value 为空都是允许的此时 value 记为空字符串。import stdx.encoding.url.* main() { // 使用带参构造函数创建 Form 实例 let form Form(nameZhangsanage30cityNanjing) }解析时还会对 key 和 value 执行自动解码%XX形式的转义序列会被还原为原始字符isQuery: true模式下也会被转换为空格见 url_util.cj。因此Form(%6AD)解析出的 value 是jD而非%6AD。异常行为字符串中包含非法转义字符如%后不是十六进制字符时抛出 UrlSyntaxException解码结果不符合 UTF-8 字节序列规则时抛出IllegalArgumentException需要注意源码中还定义了一个内置上限MAX_URL_FORM_ITEMS 4096form.cj当表单项总数超过该值时add/set/带参构造会抛出IllegalStateException防止恶意构造超大表单form.cj。二、读取get 与 getAllget获取 key 对应的第一个 valueget(key)返回OptionString当 key 存在时返回第一个value不存在时返回None。其源码实现就是取HashMapString, ArrayListString中数组的首元素form.cjpublic func get(key: String): OptionString { match (data.get(key)) { case Some(buffer) buffer.get(0) case None OptionString.None } }返回值各种情况的判定规则如下query 组件get(a)的结果说明abSome(b)正常键值对aSome()value 为空仍返回Some空串aSome()没有value 记为空串ab查询 keycNonekey 不存在重复 key 时get 返回第一个 value且值自动解码URL query 中允许同一个 key 出现多次如?122312Form会把它们存入同一数组get只取第一个。下面示例同时演示了自动解码%6A会被解码为字符j。import stdx.encoding.url.* main(): Int64 { // 从 URL 编码字符串构造 Form // %6A 会被解码为 j let form Form(231%6AD12) // 获取重复 key 的第一个 value自动解码 println(key1 的第一个 value: ${form.get(1).getOrThrow()}) return 0 }运行结果key1 的第一个 value: jD再看一个包含空值、缺失值等边界情况的完整示例import stdx.encoding.url.* main() { // 创建一个Form实例并添加一些键值对 let form Form() form.add(username, admin) form.add(email, adminexample.com) // 获取指定键的值 let usernameResult form.get(username) let emailResult form.get(email) let nonexistentResult form.get(nonexistent) println(username: ${usernameResult}) println(email: ${emailResult}) println(nonexistent: ${nonexistentResult}) }运行结果username: Some(admin) email: Some(adminexample.com) nonexistent: NonegetAll获取 key 对应的全部 value当需要处理重复 key 的所有取值例如多选标签参数tagredtagbluetaggreen时用getAll(key)获取ArrayListStringkey 不存在时返回空数组。实现上会对内部数组做一次克隆避免外部修改污染内部数据form.cjimport stdx.encoding.url.* main() { // 创建一个Form实例并添加一些键值对 let form Form() form.add(tag, red) form.add(tag, blue) form.add(tag, green) form.add(name, myForm) // 获取指定键的所有值 let tagValues form.getAll(tag) let nameValues form.getAll(name) let nonexistentValues form.getAll(nonexistent) println(tagValues: ${tagValues}) println(nameValues: ${nameValues}) println(nonexistentValues: ${nonexistentValues}) }运行结果tagValues: [red, blue, green] nameValues: [myForm] nonexistentValues: []三、修改add / set / remove / isEmpty / cloneForm的修改类操作都很直观下面这段示例把add、set、clone的前后变化一次展示清楚import stdx.encoding.url.* main(): Int64 { // 创建空的 Form 并添加键值对 let form Form() form.add(k, v1) form.add(k, v2) println(添加后keyk 的第一个 value: ${form.get(k).getOrThrow()}) // 使用 set 设置键值会覆盖之前的值 form.set(k, v) println(set 后keyk 的 value: ${form.get(k).getOrThrow()}) // 克隆 Form 并添加新的键值对 let clonedForm form.clone() clonedForm.add(k1, v1) println(克隆的 Formkeyk1 的 value: ${clonedForm.get(k1).getOrThrow()}) // 原 Form 没有键 k1返回默认值 println(原 Formkeyk1 的 value: ${form.get(k1) ?? kkk}) return 0 }运行结果添加后keyk 的第一个 value: v1 set 后keyk 的 value: v 克隆的 Formkeyk1 的 value: v1 原 Formkeyk1 的 value: kkk各方法的语义要点add(key, value)新增键值对key 已存在时把 value追加到原 value 数组末尾不覆盖已有值form.cjset(key, value)重置指定 key 的 value——覆盖原数组为单元素[value]如果 key 不存在则相当于新增form.cjremove(key)删除 key 及其全部 value删除不存在的 key 不会抛异常form.cjisEmpty()判断表单是否为空返回Boolclone()深拷贝得到新的独立Form实例对新实例的修改不影响原实例form.cj。补充remove与set的完整示例import stdx.encoding.url.* main() { // 创建一个Form实例并添加一些键值对 let form Form() form.add(username, admin) form.add(password, secret) // 移除指定的键值对 form.remove(password) // 移除不存在的键值对无异常 form.remove(nonexistent) println(toEncodeString: ${form.toEncodeString()}) }运行结果toEncodeString: usernameadminimport stdx.encoding.url.* main() { // 创建一个Form实例并添加一些键值对 let form Form() form.add(key1, value1) // 重置指定键的值 form.set(key1, newvalue1) // 重置不存在的键的值会创建新的键值对 form.set(key2, value2) println(toEncodeString: ${form.toEncodeString()}) }运行结果toEncodeString: key1newvalue1key2value2四、输出toEncodeString 的编码规则toEncodeString()把表单中的键值对编码为 URL 查询字符串。编码采用百分号编码两条关键规则见 Form 类文档 与 form.cj未保留字符不会被编码。RFC 3986 定义的未保留字符为unreserved ALPHA / DIGIT / - / . / _ / ~即字母、数字以及- . _ ~保持原样空格会编码为这是表单编码与普通 URL 编码的差异点isQuery: true模式下生效见 url_util.cj。其余特殊字符如、非 ASCII 中文等按 UTF-8 字节转成%XX。看一个混合场景import stdx.encoding.url.* main() { // 创建一个Form实例并添加一些键值对 let form Form() // 存在空格 form.add(name, Zhang san) // 存在保留字符-不会进行编码 form.add(生日, 2026-1-8) // 存在特殊字符会进行编码 form.add(email, zhangsanexample.com) // 将表单转换为编码字符串 let encodedString form.toEncodeString() println(toEncodeString: ${encodedString}) }运行结果toEncodeString: nameZhangsan%E7%94%9F%E6%97%A52026-1-8emailzhangsan%40example.com注意key 同样会参与编码如中文 key“生日”被编码为%E7%94%9F%E6%97%A5value 中的空格变、变%40而-保持原样。五、在完整场景中使用URL.queryForm 与 HTTP 请求Form不仅可以直接构造还能从解析好的 URL 上直接取到。URL类提供了queryForm属性它把解码后的查询组件直接封装成Form实例url.cj内部实现正是Form(_rawQuery)import stdx.encoding.url.* main() { // 解析URL let url URL.parse(https://example.com:8080/api/v1/users?name%E5%BC%A0%E4%B8%89age30#fragment) // 获取查询组件 let queryForm url.queryForm // 获取查询组件中的 name 值 let name queryForm.get(name) println(URL queryForm: ${name}) }运行结果URL queryForm: Some(张三)在这个例子里%E5%BC%A0%E4%B8%89被自动解码为“张三”再经queryForm.get(name)取回。在 HTTP 层面stdx.net.http的HttpRequest也直接使用了Form其form属性规定——当请求方法为POST/PUT/PATCH且Content-Type为application/x-www-form-urlencoded时form代表请求体其他方法下form代表 URL 中的查询参数见 http_request.cjpublic prop form: Form { get() { ... let f match (this._method) { case POST | PUT | PATCH match (headers.getInternal(content-type)) { case Some(hv) if (hv.splitAnyMatch(SEMICOLON, application/x-www-form-urlencoded)) { readFormBody() } else { Form() } case None Form() } case _ url.queryForm } ... } }这印证了Form在仓颉 stdx 中的典型定位前端用于解析 URL 查询串后端用于解析与构造表单请求体是 HTTP 客户端/服务端参数处理的中枢类型。六、综合实战构造、读取、修改与输出的完整流程把前文要点串成一个完整的可运行程序演示从“构造 → 读取 → 修改 → 克隆 → 输出”的全链路import stdx.encoding.url.* main(): Int64 { // 1. 从 URL 编码字符串构造 Form let form Form(122312) // 2. 读取get 获取 key 对应映射的 value println(key1 的 value: ${form.get(1).getOrThrow()}) // 3. 修改set 覆盖、add 追加 form.set(2, new3) form.add(3, a) form.add(3, b) // 4. 读取全部值 println(key3 的所有 value: ${form.getAll(3)}) // 5. 克隆并独立修改 let cloned form.clone() cloned.remove(1) println(克隆后 key1 是否存在: ${cloned.get(1)}) // 6. 输出编码串 println(toEncodeString: ${form.toEncodeString()}) return 0 }运行结果key1 的 value: 2 key3 的所有 value: [a, b] 克隆后 key1 是否存在: None toEncodeString: 2new3123a3b小结与注意事项解析侧Form(...)按分段、切分键值自动解码%XX视为空格允许无或空 value重复 key 全部保留get取第一个、getAll取全部。修改侧add追加、set覆盖、remove删除、clone深拷贝所有写操作受 4096 项上限保护。输出侧toEncodeString执行百分号编码未保留字符字母数字与-._~原样保留空格变。与生态配合URL.queryForm可从解析后的 URL 直接取表单HttpRequest.form在application/x-www-form-urlencoded场景下自动把请求体解析为Form实现查询参数与表单参数处理逻辑的统一。安全提示解析非法转义会抛 UrlSyntaxException建议在接收外部输入时捕获该异常同时Form的 4096 项上限也避免了大表单导致的资源耗尽问题。赞分享标准库网络密码学并发编程【免费下载链接】cangjie_stdx仓颉编程语言提供了 stdx 模块该模块提供了网络、安全等领域的通用能力。项目地址https://gitcode.com/Cangjie/cangjie_stdx点击查看免费下载相关推荐仓颉扩展库 stdx.encoding.urlForm 表单键值对的构造、查询与修改实战仓颉扩展库 stdx.encoding.urlForm 表单键值对的构造、查询与修改实战 Form 是仓颉编程语言扩展库 stdx.encoding.url文档知识库教程OpenHarmony仓颉 stdx URL 包完全指南URL 解析、百分号编解码与 Form 表单处理仓颉 stdx URL 包完全指南URL 解析、百分号编解码与 Form 表单处理 本指南系统讲解仓颉编程语言 stdx 标准扩展库中 stdx.encodi标准库网络密码学并发编程仓颉编程语言 stdx.encoding.url 扩展库实战URL 解析、百分号编解码与 Form 查询参数处理仓颉编程语言 stdx.encoding.url 扩展库实战URL 解析、百分号编解码与 Form 查询参数处理 仓颉编程语言扩展库stdx中的 enco文档知识库教程OpenHarmony创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考