介绍
upload4cj是用于处理浏览器或者其他客户端上传上来的单个或者多个文件的一个文件报文解析组件(注:这里的文件指字段和文件两部分)
特性:
- 🚀 支持解析单个字段或者多个字段上传上来的报文
- 💪 支持解析单个文件或者多个文件上传上来的报文
- 🌍 支持解析字段和文件一起上传上来的报文
架构图
源码目录
.
├── doc
├── src
│ ├── upload4cj
│ ├──deferredFile_output_stream.cj
│ ├──disk_file_item_factory.cj
│ ├──disk_file_item.cj
│ ├──file_item_factory.cj
│ ├──file_item_headers_impl.cj
│ ├──file_item_headers_support.cj
│ ├──file_item_headers.cj
│ ├──file_item_iterator_impl.cj
│ ├──file_item_iterator.cj
│ ├──file_item_stream_impl.cj
│ ├──file_item_stream.cj
│ ├──file_item.cj
│ ├──file_upload_base.cj
│ ├──file_upload_exception.cj
│ ├──file_upload.cj
│ ├──inter_input_stream.cj
│ ├──item_input_stream.cj
│ ├──limited_input_stream_impl.cj
│ ├──limited_input_stream.cj
│ ├──mime_utility.cj
│ ├──multipart_stream.cj
│ ├──parameter_parser.cj
│ ├──progress_listener.cj
│ ├──progress_notifier.cj
│ ├──quoted_printable_decoder.cj
│ ├──request_context.cj
│ ├──servlet_file_upload.cj
│ ├──servlet_request_context.cj
│ ├──streams.cj
│ └──thresholding_output_stream.cj
└── test
│ ├── DOC
│ ├── FUZZ
│ ├── HLT
│ └── LLT
├── CHANGELOG.md
├── gitee_gate.cfg
├── LICENSE.txt
├── module.json
├── README.md
├── README.OpenSource
doc
存放库的feature_api文档src
是库源码目录test
存放 DOC 测试用例、FUZZ 测试用例 HLT 测试用例、LLT 自测用例
接口说明
主要核心类和全局函数说明,详情见 API
使用说明
编译
Linux编译
cjpm build
Windows编译
cjpm build
功能示例
通过parseRequest解析请求报文获取fileItem
import upload4cj.*
import net.http.*
import std.io.*
import std.collection.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let ccc = Test_ReadMe()
ccc.test_readme_01()
0
}
@Test
public class Test_ReadMe{
let CONTENT_TYPE: String = "multipart/form-data; boundary=---1234"
@TestCase
func test_readme_01 () {
let text =
"-----1234\r\n" +
"content-disposition: form-data; name=\"field1\"\r\n" +
"\r\n" +
"Joe Blow\r\n" +
"-----1234\r\n" +
"content-disposition: form-data; name=\"pics\"\r\n" +
"Content-type: multipart/mixed, boundary=---9876\r\n" +
"\r\n" +
"-----9876\r\n" +
"Content-disposition: attachment; filename=\"file1.txt\"\r\n" +
"Content-Type: text/plain\r\n" +
"\r\n" +
"... contents of file1.txt ...\r\n" +
"-----9876--\r\n" +
"-----1234--\r\n"
let bytes: Array<UInt8> = text.toUtf8Array()
var output = ByteArrayStream()
output.write(bytes)
var req1 = HttpRequestBuilder().method("POST").url("http://127.0.0.1/")
.body(output).build()
req1.headers.add("Content-Type", CONTENT_TYPE)
let fileItemFactory: DiskFileItemFactory = DiskFileItemFactory()
let upload: ServletFileUpload = ServletFileUpload(fileItemFactory)
let fileItems: ArrayList<FileItem> = upload.parseRequest(req1).getOrThrow()
let field: FileItem = fileItems.get(0).getOrThrow()
@Assert(field.getFieldName(),"field1")
@Assert(field.isGetFormField(),true)
@Assert(field.getString(),"Joe Blow")
}
}
执行结果如下:
[ PASSED ] CASE: test_readme_01
通过parseParameterMap解析请求报文获取fileItem
import upload4cj.*
import net.http.*
import std.io.*
import std.collection.*
import std.unittest.*
import std.unittest.testmacro.*
main() {
let ccc = Test_ReadMe()
ccc.test_readme_02()
0
}
@Test
public class Test_ReadMe{
let CONTENT_TYPE: String = "multipart/form-data; boundary=---1234"
@TestCase
func test_readme_02 () {
let text =
"-----1234\r\n" +
"Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" +
"Content-Type: text/whatever\r\n" +
"\r\n" +
"This is the content of the file\n" +
"\r\n" +
"-----1234\r\n" +
"Content-Disposition: form-data; name=\"field\"\r\n" +
"\r\n" +
"fieldValue\r\n" +
"-----1234\r\n" +
"Content-Disposition: form-data; name=\"multi\"\r\n" +
"\r\n" +
"value1\r\n" +
"-----1234\r\n" +
"Content-Disposition: form-data; name=\"multi\"\r\n" +
"\r\n" +
"value2\r\n" +
"-----1234--\r\n"
let bytes: Array<UInt8> = text.toUtf8Array()
var output = ByteArrayStream()
output.write(bytes)
var req1 = HttpRequestBuilder().method("POST").url("http://127.0.0.1/")
.body(output).build()
req1.headers.add("Content-Type", CONTENT_TYPE)
let upload: ServletFileUpload = ServletFileUpload(DiskFileItemFactory())
let mappedParameters: Map<String, ArrayList<FileItem>> = upload.parseParameterMap(req1)
@Assert(mappedParameters.contains("file"),true)
@Assert(mappedParameters.get("file").getOrThrow().size,1)
@Assert(mappedParameters.contains("field"),true)
@Assert(mappedParameters.get("field").getOrThrow().size,1)
@Assert(mappedParameters.contains("multi"),true)
@Assert(mappedParameters.get("multi").getOrThrow().size,2)
}
}
执行结果如下:
[ PASSED ] CASE: test_readme_02
鸿蒙全栈开发全新学习指南
总是有很多小伙伴反馈说:鸿蒙开发不知道学习哪些技术?不知道需要重点掌握哪些鸿蒙应用开发知识点? 为了解决大家这些学习烦恼。在这准备了一份很实用的鸿蒙(HarmonyOS NEXT)学习路线与学习文档给大家用来跟着学习。
针对一些列因素,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。
本路线共分为四个阶段:
第一阶段:鸿蒙初中级开发必备技能
第二阶段:鸿蒙南北双向高工技能基础:gitee.com/MNxiaona/733GH
第三阶段:应用开发中高级就业技术
第四阶段:全网首发-工业级南向设备开发就业技术:gitee.com/MNxiaona/733GH
《鸿蒙 (Harmony OS)开发学习手册》(共计892页)
如何快速入门?
1.基本概念
2.构建第一个ArkTS应用
3.……
开发基础知识:gitee.com/MNxiaona/733GH
1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……
基于ArkTS 开发
1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……
鸿蒙开发面试真题(含参考答案):gitee.com/MNxiaona/733GH
OpenHarmony 开发环境搭建
《OpenHarmony源码解析》:gitee.com/MNxiaona/733GH
搭建开发环境
系统架构分析
- 构建子系统
- 启动流程
- 子系统
- 分布式任务调度子系统
- 分布式通信子系统
- 驱动子系统
- ……
OpenHarmony 设备开发学习手册
项目实战开发教学:gitee.com/MNxiaona/733GH
写在最后
- 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
- 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:
gitee.com/MNxiaona/733GH