2020-03-30

文件上传


(一)文件上传的概述


一、什么是文件上传

    文件上传:将本地的文件通过流写入到服务器的过程


二、为什么要学习文件上传

    实际开发中有很多应用:

        QQ空间上传图片

        招聘网站上传简历


三、文件上传的技术

    JSPSmartUpload:应用在JSP上的文件上传和下载的组件

    FileUpload:应用在Java环境上的文件上传的功能

    Servlet3.0:提供了文件上传的功能

    Struts2:提供了文件上传的功能


四、文件上传的三个要素

    1、表单的提交的方式需要是POST(因为GET有大小限制)

    2、表单中需要有<input type="file">元素,还需要有name属性和值

    3、表单属性必须设置enctype="multipart/form-data"

(二)文件上传的原理分析


一、抓包分析


1、没有设置enctype属性

POST /web06/jsp/upload.jsp HTTP/1.1

Host: localhost:8080

Connection: keep-alive

Content-Length: 23

Cache-Control: max-age=0

Origin: http://localhost:8080

Upgrade-Insecure-Requests: 1

Content-Type: application/x-www-form-urlencoded

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36

Sec-Fetch-User: ?1

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

Sec-Fetch-Site: same-origin

Sec-Fetch-Mode: navigate

Referer: http://localhost:8080/web06/jsp/upload.jsp

Accept-Encoding: gzip, deflate, br

Accept-Language: zh-CN,zh;q=0.9

Cookie: JSESSIONID=5EC0B8AC2ED01283DEE896BC835C05FB


info=aaa&upload=aaa.txt

        *注意:没有文件上传中的文件的具体内容


2、设置enctype属性

POST /web06/jsp/upload.jsp HTTP/1.1

Host: localhost:8080

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2

Accept-Encoding: gzip, deflate

Content-Type: multipart/form-data; boundary=---------------------------66193578536799190642897124112

Content-Length: 344

Origin: http://localhost:8080

Connection: keep-alive

Referer: http://localhost:8080/web06/jsp/upload.jsp

Cookie: JSESSIONID=00D32978472B2FE2E35796855713EE40; Pycharm-8dbeb98c=1f31b81e-d44c-45f8-95c1-2b06c10aea65

Upgrade-Insecure-Requests: 1


-----------------------------66193578536799190642897124112

Content-Disposition: form-data; name="info"


aaa

-----------------------------66193578536799190642897124112

Content-Disposition: form-data; name="upload"; filename="aaa.txt"

Content-Type: text/plain


hello world!!

-----------------------------66193578536799190642897124112--



二、文件上传的原理分析

手动实现文件上传:

(1)获得分割线

(2)获得请求体的所有内容:request.getInputStream();

(3)利用分割线将获得内容进行分割

(4)判断是普通项还是文件上传项

普通项:获得普通项名称和值

文件上传项:获得文件名称和文件内容,通过流写到服务器上


(三)文件上传的代码实现


一、引入文件上传的相关jar包

 

(四)文件上传的API


一、DiskFileItemFactory:磁盘文件项工厂

1、构造方法:

DiskFileItemFactory()

DiskFileItemFactory(int sizeThreshold, File repository)

sizeThreshold:用来设置文件上传的缓冲区的大小,默认值为10KB

repository:用来设置文件上传过程中所产生的临时文件存放的路径



2、方法:

setRepository(File repository):设置缓冲区的大小

setSizeThreshold(int sizeThreshold):设置临时文件存放的路径

3、API的使用的代码

 

二、ServletFileUpload:核心解析类


1、构造方法

ServletFileUpload()

ServletFileUpload(FileItemFactory fileItemFactory)


2、方法

isMultipartContent(HttpServletRequest request)

是用来判断表单的enctype属性是否正确

parseRequest(HttpServletRequest request)

解析Request对象,返回一个List集合(每个部分的对象FileItem)



(long fileSizeMax)

用来设置单个文件的大小

setSizeMax(long sizeMax)

用来设置上传的文件的总大小

setProgressListener(ProgressListener pListener)

设置监听文件上传的进度


三、FileItem文件项


1、方法

isFormField()

判断表单项是普通项还是文件上传项,如果为true代表是普通项


2、普通项的方法

getFieldName()

用来获得普通项的名称


getString()

用来获取普通项的值


getString(String encoding)

用来获取普通项的值(可解决乱码问题)


3、文件上传项

getName()

获得上传文件的文件名的方法


getInputStream()

获得上传文件的文件内容的方法


getSize()

获得上传文件的文件大小


delete()

删除文件上传过程中的临时文件

(八)文件上传同一个目录下存放文件过多的问题及解决


一、问题描述

    现在所有的用户都上传文件,如果网站访问量比较大,如果都上传到同一个目录下,此目录下存放的文件太多了,也会对程序有影响(在打开该目录的时候都会很卡,更别说读写了,效率会更低)


二、问题解决


1、目录分离

按时间分离:按月、周、天、小时

按用户分离:按张三、李四

按个数分离:一个目录下存放3000个文件

按目录分离分离算法:按照某种特定算法进行分离

上传一个文件,得到一个唯一的文件名

获取唯一文件名的hashCode值——int类型的值(占8个字节32位)

让hashCode的值& 0xf;——得出的这个值作为一级目录

让hashCode右移4位再 & 0xf;——得出的这个值作为二级目录

依此类推……


2、分析算法:、

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容