不知道你的体会是什么,我从C切换到Rust以来,最大的感受并不是语法方面的---那些方面已经有足够多人抱怨而又享受着了。我最大的感受是终于把Web编程工具,同系统编程工具统一了起来。

C/C++其实也有很多不错的Web编程框架,只是依然总感觉味道不对。所以平常Node.Js / Golang /Python都会穿插在工作中。无论是开发效率,还是维护的方便程度,C/C++在Web开发方面还是弱项。

Rust让这种情况彻底改观。Rust本身在系统开发方面就有不错的表现,社区中又出现了不少优秀的开源框架提供Web编程支持。

这其中老牌的Actix和新秀Rocket是用的比较多的两个。个人其实用Actix多一些,毕竟出来时间长,性能评测得分又比较高,社区还有比较好的支持。比如解决MultiPart FormData上传已经有了好用的工具箱awmp。

但作为万年不变的乙方代表,很多时候对于开发环境的选择还是做不到完全自主。Rocket也是不时的会用一下,Rocket易用性更好,上手容易。对于文件上传,工具本身也提供了一些粗糙的支持,但跟awmp比还是差了很多。

在对网上各种资源仔细搜索寻找之后,决定还是自己来写一个,这就是今天的rocket_upload。

工具背后做了很多事情来解析MultiPart FormData, 但用起来还是非常容易。

要做的事情只有三个,首先,在Cargo.toml文件中加入rocket-upload依赖:

rocket_upload = "*"

第二,是在程序一开始对rocket_upload做引用:

use rocket_upload::MultipartDatas;

最后,则是在请求处理函数中使用了,来看代码:

#[post("/upload/<userid>", data = "<data>")]
fn upload(userid: String, content_type: &ContentType, data: MultipartDatas) -> Html<String>
{
// 获取在路径中嵌入的用户参数,只是演示同原有系统之间的兼容性,无实际意义
let mut result=format!("UserID:{}<br>",userid);
// content_type在这里并没有使用,所以实际可以在函数声明中取消这个变量,但如果想了解MultiPart的更多信息,还是可以用
result = format!("{}{:?}<br>",result,content_type);
// 获取用户网页表单中其它的字段值
for t in data.texts {
result = format!("{}FieldName:{} --- FieldValue:{}<br>",result,t.key,t.value);
}
// 获取用户表单中上传的文件,支持多个文件的上传
for f in data.files {
result = format!("{}FieldName:{} --- FileName:{} --- StoragePath:{}<br>",
result,f.name,f.filename,f.path);
// 文件在rocket-upload处理后,会保存在/tmp目录,下面的命令把文件拷贝到自己定义的上传文件夹
f.persist(Path::new("upload"));
}
// 在反馈的网页中显示所有获取到的数据信息
Html(format!("<html><head></head><body>upload coming...<br>{}</body></html>",result))
}

就我当前找遍全网的经历来看,这算最简单的MultiPart处理工具了吧。

对应的,把网页表单的代码也贴出来对比来看一下:

<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta content="always" name="referrer">
<title>upload</title>
<body link="#0000cc" style="">
<form id="data" enctype="multipart/form-data" method="post" action="/upload/334445566">
<div class="row">
name:<input type="text" name="name"><br/>
information:<input type="text" name="info"><br/>
Select files wanna upload , and click at "UPLOAD" button.<br /><br/>
<input type="file" name="files" multiple>
</div>
<div class="row">
<button type="submit" value="UPLOAD">UPLOAD</button>
</div>
</form>
</body>
</html>

简单来说,在请求处理函数中,原有Restful风格,在URL中嵌入的变量,仍然采用Rocket原有的方式来声明和处理。

随后是MultipartDatas类型的变量,在本例中是data。

变量结构类型分为两个部分,成员texts中包含表单中除上传文件之外的字段,字段名称保存在key成员变量中,值保存在value成员变量中。

files则包含表单中上传的文件,如果只有一个文件上传,那就是files[0]。表单字段名称保存在name成员,单独的文件名,也就是来自于MultiPart数据中的,保存在成员filename,缓存文件的完整路径保存在path成员。

因为缓存的文件在请求处理函数完成后就超出了作用域,从而被自动删除。所以如果想把文件长久保存下来,可以自己建立一个文件夹比如upload,然后使用f.persist(Path::new("upload"));把文件拷贝过去。

这是使用拷贝而不是移动,是因为在很多系统中,/tmp文件夹往往是内存卷,跟硬盘并不是同一个存储设备,直接移动的话,在某些系统中可能会报错,也无法真正将文件保存起来。

源码仓库地址:https://github.com/formoon/rocket-upload

本工具编写的时候,参考了原有的一个rocket扩展:https://crates.io/crates/rocket-multipart-form-data

Rocket框架多文件上传,介绍rocket_upload 使用的更多相关文章

  1. SpringMVC框架06——文件上传与下载

    1.文件上传 Spring MVC框架的文件上传是基于commons-fileupload组件的文件上传,只不过Spring MVC框架在原有文件上传组件上做了进一步封装,简化了文件上传的代码实现. ...

  2. jersey框架实现文件上传

    jersey框架是一个开源的RESTful的框架,实现了实现了JAX-RS规范,进一步地简化 RESTful service 和 client 开发.当然而且是必须的,jersey对文件的上传和下载也 ...

  3. layUI框架中文件上传前后端交互及遇到的相关问题

    下面我将讲述一下我在使用layUI框架中文件上传所遇到的问题: 前端jsp页面: <div class="layui-form-item"> <label cla ...

  4. 使用SpringMVC框架实现文件上传和下载功能

    使用SpringMVC框架实现文件上传和下载功能 (一)单个文件上传 ①配置文件上传解释器 <!—配置文件上传解释器 --> <mvc:annotation-driven>&l ...

  5. node.js使用express框架进行文件上传

    关于node.js使用express框架进行文件上传,主要来自于最近对Settings-Sync插件做的研究.目前的研究算是取得的比较好的进展.Settings-Sync中通过快捷键上传文件,其实主要 ...

  6. 关于我使用spring mvc框架做文件上传时遇到的问题

    非常感谢作者 原文:https://blog.csdn.net/lingirl/article/details/1714806 昨天尝试着用spring mvc框架做文件上传,犯了挺多不该犯的毛病问题 ...

  7. 笨鸟先飞之Java(一)--使用struts2框架实现文件上传

    无论是.net还是Java,我们最常接触到的就是文件的上传和下载功能,在Java里要实现这两个经常使用功能会有非常多种解决方案,可是struts2的框架却能给我们一个比較简单的方式,以下就一起来看吧: ...

  8. 第三百一十九节,Django框架,文件上传

    第三百一十九节,Django框架,文件上传 1.自定义上传[推荐] 请求对象.FILES.get()获取上传文件的对象上传对象.name获取上传文件名称上传对象.chunks()获取上传数据包,字节码 ...

  9. Android(java)学习笔记214:开源框架的文件上传(只能使用Post)

    1.文件上传给服务器,服务器端必然要写代码进行支持,如下: 我们新建一个FileUpload.jsp的动态网页,同时我们上传文件只能使用post方式(不可能将上传数据拼凑在url路径下),上传数据Ap ...

随机推荐

  1. 2018.8.1 python中字典的增删改查及其它操作

    一.字典的简单介绍 1.dict 用{}来表示       键值对数据           {key:value} 唯一性 2.键都必须是可哈希,不可变的数据类型就可以当做字典中的键 值没有任何限制 ...

  2. Android_Fragment栈操作 commit()问题分析

    栈操作时遇到一个问题 getFragmentManager().beginTransaction() .replace(R.id.fl_container,bFragment) .addToBackS ...

  3. 一位年轻而优秀的.NET开发者的成长点滴

    一,社区的小圈子 今年3月的一次技术交流活动上,那是我们.NET技术社区第一次组织线下活动,由于没什么经验,所以活动组织得比较仓促,内容也比较一般,效果还是有点欠缺.当然,活动本身是必要的,这次活动上 ...

  4. if __name__ == "__main__" 的作用

    作用:当模块被直接运行时,以下代码块将被运行,当模块是被导入时,代码块不被运行. 例子: # file one.py def func(): print("func() in one.py& ...

  5. 前端与算法 leetcode 1. 两数之和

    目录 # 前端与算法 leetcode 1. 两数之和 题目描述 概要 提示 解析 解法一:暴力法 解法二:HashMap法 算法 传入[1, 2], [11, 1, 2, 3, 2]的运行结果 执行 ...

  6. csps模拟测试 77爆零反思

    题不算太难,可是我还是没考出应有水平. $1h8min$切掉前两道题,然后$T3$想到正解并且码出来了并且过了大样例并且爆零. 没什么好说的,我太自信了,没打对拍? 想到了正解,还不如随便打个暴力分高 ...

  7. MapReduce任务提交源码分析

    为了测试MapReduce提交的详细流程.需要在提交这一步打上断点: F7进入方法: 进入submit方法: 注意这个connect方法,它在连接谁呢?我们知道,Driver是作为客户端存在的,那么客 ...

  8. python经典算法题目:找出这两个有序数组的中位数

    题目:找出这两个有序数组的中位数 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以 ...

  9. vue登录功能和将商品添加至购物车实现

     2.1: 学子商城--用户登录 用户登录商城用户操作行为,操作用户输入用户名和密码 点击登录按钮,一种情况登录成功 一种情况登录失败 "用户名或密码有误请检查" 2.2:如何实现 ...

  10. ADO.NET学习心得《一》

    大家好,我是代号六零一,很高兴又开始重启博客了,为了更好的加深自己的记忆和复习,今天开始坚持写写心得体会,刚开始学习ADO.NET的时候也是一脸懵逼的,代码只有动手敲打才会知道其实并不难,只要多敲几遍 ...