JavaWeb中文件上传与下载
admin
2024-04-16 09:46:29
0

JavaWeb中文件上传与下载

一、文件上传

1.文件上传的应用

比如个人信息的管理,上传头像
比如商品信息的管理,上传商品的图片
这些都需要通过浏览器客户端将图片上传到服务器的磁盘上

文件上传原理
所谓的文件上传就是服务器端通过request对象获取输入流,将浏览器端上传的数据读取出来,保存到服务器端

2.客户端浏览器注意事项

1.请求方式必须是 post
2.需要使用组件
3.表单必须设置enctype=“multipart/form-data”

3.服务器端处理

通过request对象,获取InputStream, 可以将浏览器提交的所有数据读取到.

4.上传开源框架-commons-upload

Apache 开源组织提供了一个用来处理表单文件上传的一个开源组件( Commons-fileupload ),该组件性能优异,并且其API使用极其简单,可以让开发人员轻松实现web文件上传功能,因此在web开发中实现文件上传功能,通常使用Commons-fileupload组件实现。

使用Commons-fileupload组件实现文件上传,需要导入该组件相应的支撑jar包:Commons-fileupload和commons-io,
commons-io 不属于文件上传组件的开发jar文件,但Commons-fileupload 组件从1.1 版本开始,它工作时需要commons-io包的支持

5.文件上传案例

在浏览器端创建一个可以上传文件的表单,在服务器端通过commons-fileupload完成文件上传。
浏览器端注意三件事情:
1.表单的method=post
2.设置enctype=multipart/form-date
3.使用具有name属性的file元素
在服务器端
1.创建DiskFileItemFactory
2.创建ServletFileUpload
3.通过ServletFileUpload的parseRequest方法得到所有的FileItem

1.设置浏览器端

2.在服务器端操作

关键类:
DiskFileItemFactory:ServletFileUpload工厂类
ServletFileUpload:用于处理文件上传的类
IOUtils:文件上传IO流类
BeanUtils:存储表单内文本信息类

//设置乱码
upload.setHeaderEncoding(“UTF-8”);

//ServletFileUpload工厂类
DiskFileItemFactory factory = new DiskFileItemFactory();
//处理文件上传的类
ServletFileUpload upload = new ServletFileUpload(factory);
try {
//获得表带内容List items = upload.parseRequest(request);for(FileItem fileItem : items) {if(!fileItem.isFormField()){//判断非文本信息FileOutputStream fos = new 							  									FileOutputStream("C:\\test.jpg");IOUtils.copy(fileItem.getInputStream(),fos);//拷贝fos.close();}}
} catch (FileUploadException e) {
e.printStackTrace();
}

完善细节
1.设置保存上传文件的服务器目录

DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
try {List items = upload.parseRequest(request);for(FileItem fileItem : items) {if(!fileItem.isFormField()){//获取项目在当前系统下的路径+"upload"String path = this.getServletContext().getRealPath("Nupload");File dir = new File(path);if(!dir.exists())){/判断文件夹是否存在dir.mkdirs();}String filename = fileItem.getName();//获得当前上传文件的名字FileOutputStream fos = new FileOutputStream(new File(dir,filename));IOUtils.copy(fileItem.getInputStream(),fos);fos.close();1
} catch (FileUploadException e) {e.printStackTrace();
}

2.解决上传文件名是中文的问题,通过item.getName()获取到文件的名称

a)直接将其改名,不用原来的名字
b)保存其中文的名字(注意,一般如果是压缩文件供下载的资源,则可以考虑保留其中文名称,否则一般图片直接展示用的,不建议用中文名来保存)

思考题:文件名重复了怎么办?
问题:覆盖
解决方案:
客户端参与
方案一:做个文件名的唯一性校验,告诉客户端,这个文件名已经存在(不建议)
服务端解决
方案二:重新取个名字(唯一性:时间、UUID)—图片资源
利用时间保证唯一性:System.currentTimeMillis()

6.利用UUID保证唯一性

DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
try {List items = upload.parseRequest(request);for(FileItem fileItem : items) {if(!fileItem.isFormField())[//获取项目在当前系统下的路径+"upload"String path = this.getServletContext().getRealPath("\\upload");File dir = new File(path);if(!dir.exists()){//判断文件夹是否存在dir.mkdirs();}UUID randomUUID = UUID.randomUUID();String filename = randomUUID + "_" + fileItem.getName();//获得当前上传文件的名字			FileOutputStream fos = new FileOutputStream(new File(dir,filename));IOUtils.copy(fileItem.getInputStream(),fos);fos.close();}

2,方案三:下载电影压缩包,水野朝阳.zip 保留原有的名字

for(FileItem fileItem : items) {if(!fileItem.isFormField()){//获取项目在当前系统下的路径+"upload"String path = this.getServletContext().getRealPath("\\upload");File dir = new File(path);if(!dir.exists()){//判断文件夹是否存在dir.mkdirs();
}//在原来路径的基础上添加时间路径,做到图片不覆盖的效果Date date = new Date();SimpleDateFormat sdf = new SimpleDateFormat("yyyy/M/dd/hhmmss");String datePath = sdf.format(date);File uploadDir = new File(dir,datePath);if(!uploadDir.exists())[uploadDir.mkdirs();}String filename = fileItem.getName());//获得当前上传文件的名字FileOutputStream fos = new FileOutputStream(new File(uploadDir,filename));IOUtils.copy(fileItem.getInputStream(),fos);fos.close();
}

7.获取完整的表单数据

保存一个完整的表单信息,除了将文件上传到服务器以外,还需要将其他表单项信息保存到对象,并存储到数据中心,而对应的图片信息则保存为保存的路径即可。
那么怎么获取到其他的表单项数据?item.getFileName(),item.getString()
为了更好完成对其他表单项的值的获取,需要借助另一个开源框架 BeanUtils
它除了自身的jar包,还依赖于commons-logging.jar

//创建一个Map来存储普通的表单项数据
Mapmap = new HashMap<>();
//创建一个对象来存储各项数据
Book book = new Book();for(FileItem item : list){if(item.isFormField()){//普通表单项//System.out.println(item.getFieldName()+":"+item.getString("utf-8"));//实现一个通用的方法来将对应的参数都赋值到对象上map.put(item.getFieldName(),item.getString("utf-8"));}else{//上传文件//创建上传的目录File dir = new File(this.getServletContext().getRealPath("/upload"));if(!dir.exists()){dir.mkdirs();}//设置文件名的唯一性String fileName = item.getName();fileName = FilenameUtils.getName(fileName);fileName = UUID.randomUUID()+"_"+fileName;//上传文件FileOutputStream outputStream = new FileOutputStream(new File(dir, fileName));IOUtils.copy(item.getInputStream(),outputStream);book.setImgUrl("upload"+File.separator+fileName);outputStream.close();}item.delete();}BeanUtils.populate(book,map);
}		

细节:
有复选框的情况怎么办?

String name = fileItem.getFieldName();
String value = fileItem.getString("UTF-8");if(map.get(name) == null){map. put(name, value);}else{map.put(name, map.get(name)+"," + value);
}

8.多文件上传案例

实现多文件的批量上传

Ps:展示图片-“upload” + File.separator + datePath + File.separator + filename);

二、文件下载

主要实现方式有两种
1.超链接下载
2.以超练级的方式下载压缩文件
3.以超链接的方式下载图片文件
4.以超链接的方式下载中文文件名的文件
5.Servlet下载

有些超链接搞不定的事情就交给Servlet来搞定

下载photo.zip
下载pipixia.jpg
下载头像.zip

采用流的方式来读和写

设置响应的头部信息(告诉客户端是以附件的形式下载)
response.setHeader(“Content-disposition”, “attachment;fileName=”+fileName);
细节:
下载的文件名是中文怎么办?

String realPath = this.getServletContext().getRealPath("download\\头像.zip");
String fileName = realPath.substring(realPath.lastIndexof(")+1);
fileName = URLEncoder.encode(fileName,"UTF-8");
response.setHeader("Content-disposition","attachment;fileName="+fileName);
FileInputStream fis = new FileInputStream(realPath);
ServletOutputStream outputStream = response.getOutputStream();
byte[] b = new byte[1024];
int len = 0
while((len = fis.read(b)) != -1){outputStream.write(b,0,len);
}
fis.close();
outputStream.close();
}

三、上传与下载

1.上传

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;@WebServlet(urlPatterns = "/upload")
@MultipartConfig(fileSizeThreshold = 1024*100,maxFileSize = 1024*1024*5,maxRequestSize = 1024*1024*25)
public class UploadServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String bookName=   request.getParameter("bookName");System.out.println("bookName:"+bookName);Part part= request.getPart("bookPic");String filename= part.getSubmittedFileName();String path="/WEB-INF/upload/"+filename;// 把逻辑路径转成物理路径// 绝对路径 相对路径不一样的path=request.getServletContext().getRealPath(path);System.out.println(path);part.write(path);response.getWriter().print(filename+"上传成功");}
}

2.下载

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;@WebServlet(urlPatterns = "/download")
public class DownloadServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String filename="ggc.docx";String path="/WEB-INF/upload/"+filename;path=request.getServletContext().getRealPath(path);File file=new File(path);//准备好了输入流InputStream inputStream=new FileInputStream(file);response.setHeader("Content-Disposition", "attachment;filename="+filename);//浏览器端的输出流OutputStream outputStream= response.getOutputStream();byte[] datas=new byte[1024];int len=0;while( (len =inputStream.read(datas))>0){outputStream.write(datas,0,len);}outputStream.close();inputStream.close();}
}

3.前端

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

文件上传


书名:
附件:

相关内容

热门资讯

部落荣耀安卓和苹果系统,安卓与... 亲爱的手机游戏爱好者们,你是否曾在闲暇时光里,被一款充满激情与挑战的手机游戏所吸引?今天,我要跟你聊...
如何清除安卓系统备份,轻松恢复... 手机里的备份文件越来越多,是不是感觉安卓系统都快要被它们塞爆了呢?别急,今天就来教你怎么轻松清除安卓...
大话手游安卓系统要求,安卓系统... 你有没有发现,最近大话手游在安卓平台上可是火得一塌糊涂啊!不少小伙伴都跃跃欲试,想要加入这场奇幻的冒...
哪种安卓手机系统像苹果,揭秘模... 你有没有想过,为什么苹果的iOS系统能够那么吸引人?是不是也想拥有一款既酷炫又流畅的安卓手机呢?今天...
安卓系统无响应怎么关,安卓系统... 手机突然卡住了,安卓系统无响应,这可怎么办?别急,让我来给你支个招,让你轻松解决这个棘手的问题!一、...
早教机器人安卓系统,智能育儿新... 你有没有想过,在宝宝咿呀学语的时候,有一个智能的小伙伴陪伴在他们身边,那会是多么温馨的画面呢?没错,...
凭啥放弃安卓系统了,揭秘放弃安... 你有没有想过,为什么有些人会突然放弃安卓系统,转投其他阵营的怀抱呢?这背后可是有着不少故事和原因哦!...
安卓系统放ppt模板,基于安卓... 你有没有遇到过这种情况:手机里存了好多精美的PPT模板,但是一到要用的时候,却因为安卓系统的限制而头...
一加8初始安卓系统,探索安卓系... 你有没有注意到,最近手机圈里又掀起了一股热潮?没错,就是一加8系列的发布!这款手机一经亮相,就吸引了...
oppor831s安卓系统,深... 你有没有听说最近OPPO出了一款新机——OPPO831s?这款手机可是安卓系统的大热门呢!今天,就让...
安卓监听系统时间变化,Andr... 安卓监听系统时间变化的奥秘在数字化时代,智能手机已经成为我们生活中不可或缺的一部分。它不仅仅是一个通...
橙子系统跟安卓系统哪个好,谁更... 你有没有想过,手机里那个小小的操作系统,竟然能决定你的手机体验?今天,咱们就来聊聊这个热门话题:橙子...
安卓10小米升级系统,畅享智能... 你知道吗?最近安卓10系统的大潮席卷而来,小米的粉丝们可是兴奋得不得了!这不,小米官方宣布,旗下的多...
安卓系统热点在什么位置,热点生... 你有没有遇到过这种情况:手机里明明有热点功能,但是就是找不到它在哪个位置?别急,今天就来给你详细揭秘...
安卓系统热点软件叫什么,解锁无... 你有没有想过,当你手机信号不好,又急需连接Wi-Fi的时候,安卓系统里有个神奇的软件能帮你大忙?没错...
安卓系统怎么关闭多任务,安卓系... 手机里的安卓系统是不是有时候让你眼花缭乱,那么多应用,那么多任务,有时候真想一键关闭它们,让手机清爽...
安卓鸿蒙更新不了系统,安卓用户... 最近是不是有不少安卓用户在烦恼,手机上的鸿蒙系统怎么就更新不了呢?这可真是让人头疼啊!别急,今天就来...
安卓系统的其他怎么删除,其他应... 手机里的安卓系统是不是越来越臃肿了?别急,今天就来教你怎么轻松删除那些不再需要的应用和文件,让你的手...
安卓系统降低到4.4,回顾经典... 你知道吗?最近安卓系统界可是掀起了一阵小小的风波呢!那就是——安卓系统版本降低到4.4。这可不是一件...
如何卸载安卓系统应用,轻松告别... 手机里的应用越来越多,是不是感觉内存不够用了?别急,今天就来教你怎么轻松卸载安卓系统应用,让你的手机...