Javaweb向服务器上传文件以及从服务器下载文件的方法
先导入jar包
commons-fileupload是Apache开发的一款专门用来处理上传的工具,它的作用就是可以从request对象中解析出,用户发送的请求参数和上传文件的流。
commons-fileupload包依赖commons-io,两个包需要同时导入。
tomcat内置的jar包只能在tomcat服务器使用。
上传文件的方法
1、创建DiskFileItemFactory工厂类的实例
DiskFileItemFactory dfif=new DiskFileItemFactory();//new 一个DiskFileItemFactory对象
DiskFileItemFactory类介绍
工厂类,用于创建ServletFileUpload,设置缓存等
该类一般直接使用构造器直接创建实例
方法:
public void setSizeThreshold(int sizeThreshold)
用于设置缓存文件的大小(默认值10kb)
public void setRepository(File repository)
用于设置缓存文件位置(默认系统缓存目录)
2、获取ServletFileUpload解析器的实例
ServletFileUpload sfu=new ServletFileUpload(dfif);//通过DiskFileItemFactory对象获取ServletFileUpload解析器实例
ServletFileUpload类介绍
该类用于解析request对象从而获取用户发送的请求参数(包括普通参数和文件参数)
该类需要调用有参构造器创建实例,构造器中需要一个DiskFileItemFactory作为参数
方法:
public List<FileItem> parseRequest(HttpServletRequest request)
解析request对象,获取请求参数,返回的是一个List,List中保存的是一个FileItem对象,一个对象代表一个请求参数。
public void setFileSizeMax(long fileSizeMax)
设置单个文件的大小限制,单位为B 如果上传文件超出限制,会在parseRequest()抛出异常FileSizeLimitExceededException。
public void setSizeMax(long sizeMax)
限制请求内容的总大小,单位为B 如果上传文件超出限制,会在parseRequest()抛出异常SizeLimitExceededException。
3、获取请求参数列表
List<FileItem> list = sfu.parseRequest(request);//用ServletFileUpload解析器对象获取参数列表,该列表包含文件参数和普通参数
FileItem类介绍
该类用于封装用户发送的参数和文件,也就是用户发送来的信息将会被封装成一个FileItem对象,我们通过该对象获取请求参数或上传文件的信息。
该类不用我们手动创建,由ServletFileItem解析request后返回。
方法:
String getFieldName()
获取表单项的名字,也就是input当中的name属性的值。
String getName();
获取上传的文件名,普通的请求参数为null。
String getString(String encoding);
获取内容l 若为文件,将文件的流转换为字符串。l 若为请求参数,则获取请求参数的value。
encoding参数需要指定一个字符集,不指定时中文会乱码,建议设置utf-8
boolean isFormField();
判断当前的FileItem封装的是普通请求参数,还是一个文件。如果为普通参数返回:true l 如果为文件参数返回:false
String getContentType();
获取上传文件的MIME类型
long getSize();
获取内容的大小
上传文件的例子
jsp的代码
<form action="${pageContext.request.contextPath }/Files"
method="post" enctype="multipart/form-data">
文件1:<input type="file" name="file1"><br>
<br>文件2: <input type="file" name="file2"><br>
<br> 文件3:<input type="file" name="file3"><br>
<br> 文本:<input type="text" name="text"><br>
<br> <input type="submit" value="上传">
</form>
servlet的代码
DiskFileItemFactory dfif = new DiskFileItemFactory();// 创建工厂类
ServletFileUpload sfu = new ServletFileUpload(dfif);// 创建请求解析器
sfu.setFileSizeMax(1024 * 1024 * 1);// 设置上传单个文件的的大小
sfu.setSizeMax(1024 * 1024 * 1 * 10);// 设置上传总文件的大小
response.setContentType("text/html;charset=utf-8");// 设置响应内容的编码
try {
List<FileItem> list = sfu.parseRequest(request);// 解析请求信息,获取FileItem的集合
for (FileItem fileItem : list) {// 遍历集合
if (fileItem.isFormField()) {// 如果是普通的表单项
String fieldName = fileItem.getFieldName();// 获取参数名
String value = fileItem.getString("utf-8"); // 获取参数值,设置编码为utf-8防止中文乱码
System.out.println(fieldName + " = " + value);
} else {// 如果是文件表单项
String fileName = fileItem.getName();// 获取文件名
String realPath = getServletContext().getRealPath("/upload");// 获取上传路径
System.out.println(realPath);
File f = new File(realPath);// 检查upload文件夹是否存在
if (!f.exists()) {//如果不存在则创建
f.mkdir();
}
String prefix = UUID.randomUUID().toString().replace("-", "");// 为避免重名生成一个UUID作为文件名的前缀,并且将生成UUID中的-移除
fileItem.write(new File(realPath + "/" + prefix + "_" + fileName));// 将文件写入到服务器中
fileItem.delete();// 清除文件缓存
}
}
} catch (Exception e) {
if (e instanceof SizeLimitExceededException) {
response.getWriter().print("上传文件的总大小不能超过10M");// 文件总大小超出限制
} else if (e instanceof FileSizeLimitExceededException) {
response.getWriter().print("上传单个文件的大小不能超过1M");// 单个文件大小超出限制
}
}
response.getWriter().print("上传成功");
下载文件的方法
文件下载最直接的方法就是把文件直接放到服务器的目录中,(eclipse下可以用tc工具快速访问到tomcat的工作目录,具体看我另一片博客)用户直接访问该文件就可以直接下载。但是实际上这种方式并不一定好用,比如我们在服务器上直接放置一个MP3文件,然后通过浏览器访问该文件的地址,如果是IE浏览器可能就会弹出下载窗口,而如果是FireFox和Chrome则有可能直接播放。再有就是有一些文件我们是不希望用户可以直接访问到的,这是我们就要通过Servlet来完成下载功能。
下载文件的几个关键点
1、 服务器以一个流的形式将文件发送给浏览器。
2、发送流的同时还需要设置几个响应头,来告诉浏览器下载的信息。
具体响应头如下:
Content-Type:下载文件的MIME类型,
可以通过servletContext. getMimeType(String file)获取,
也可以直接手动指定,
使用response.setContentType(String type);
响应头样式:Content-Type: audio/mpeg
Content-Disposition:下载文件的名字,
主要作用是提供一个默认的用户名,
通过response.setHeader("Content-Disposition", disposition)设置
响应头样式:Content-Disposition: attachment; filename=xxx.mp3
Content-Length: 下载文件的长度,用于设置文件的长处(不必须)
通过response. setContentLength(int len)设置。
设置后样式:Content-Length: 3140995
3、 接下来需要以输入流的形式读入硬盘上的文件
FileInputStream is = new FileInputStream(file);
这个流就是我们一会要发送给浏览器的内容
4、通过response获取一个输出流,并将文件(输入流)通过该流发送给浏览器
获取输出流 ServletOutputStream out = response.getOutputStream();
通过输出流向浏览器发送文件(不要忘了关闭输入流)
byte[] b = new byte[1024];
int len = 0;
while((len=is.read(b))> 0){
out.write(b, 0, len);
}
is.close();
下载的例子
servlet代码
String realPath = getServletContext().getRealPath("/WEB-INF/download/风吹麦浪.mp3");// 获取文件真实地址
File file = new File(realPath);// 获取file对象
if (!file.exists()) {// 找不到目标文件
response.getWriter().print("文件不存在");
return;
}
FileInputStream fis = new FileInputStream(file);// 获取文件输入流
String contentType = getServletContext().getMimeType(realPath);// 获取文件的MIME信息
String filename = file.getName();// 设置下载文件的名字
//设置编码格式,否则文件名为中文时会乱码
String ua = request.getHeader("User-Agent");// 获取客户端信息
if (ua.contains("Firefox")) {// 判断客户端是否为火狐
filename = "=?utf-8?B?" + new BASE64Encoder().encode(filename.getBytes("utf-8")) + "?=";// 若为火狐使用BASE64编码
} else {
filename = URLEncoder.encode(filename, "utf-8");// 否则使用UTF-8
}
String disposition = "attachment; filename=" + filename;// 创建Content-Disposition信息
long size = file.length();// 获取文件长度
response.setContentType(contentType);// 设置Content-Type
response.setHeader("Content-Disposition", disposition);// 设置Content-Disposition
response.setContentLength((int) size);// 设置文件长度
ServletOutputStream out = response.getOutputStream();// 通过response获取输出流,用于向浏览器输出内容
byte[] buffer = new byte[1024];// 将文件输入流通过输出流输出
int len = 0;
while ((len = fis.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
fis.close();// 最后不要忘记关闭输入流,输出流由Tomcat自己处理,不用手动关闭
编码问题
从服务器获取浏览器发送的非文件内容包含中文时,需要设置编码,如String value = fileItem.getString("utf-8"); // 获取参数值,设置编码为utf-8防止中文乱码,不设置则会乱码;
从服务器向浏览器发送中文时,需要对内容进行URL编码。(其他编码问题请看另一篇博客,里边会记录我遇到过的编码问题)
大部分浏览器使用如下方式即可解决乱码问题:URLEncoder.encode(fileName, "utf-8");但是火狐默认以Base64来解码的,所以要为火狐单独处理。
可以使用如下代码来判断浏览器的类型,然后进行不同的编码处理
就是上面例子中使用的方法
//设置编码格式,否则文件名为中文时会乱码
String ua = request.getHeader("User-Agent");// 获取客户端信息
if (ua.contains("Firefox")) {// 判断客户端是否为火狐
filename = "=?utf-8?B?" + new BASE64Encoder().encode(filename.getBytes("utf-8")) + "?=";// 若为火狐使用BASE64编码
} else {
filename = URLEncoder.encode(filename, "utf-8");// 否则使用UTF-8
}
还有一种简单但还不理解的方式,亲测可用
向将字符串用gbk进行解码,然后在使用iso8859-1进行编码
filename = new String(filename.getBytes("gbk"),"iso8859-1");
SpringMVC上传文件
Spring MVC 上下文中默认没有为文件上传提供直接的支持,因此默认情况下不能处理文件的上传工作,如果想使用 Spring 的文件上传功能,需现在上下文中配置 CommonsMultipartResovler:
1、与上面一样同样需要导入jar包
2、在SpringMVC配置文件中配置CommonsMultipartResovler
<!-- 配置CommonsMultipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<!-- 以字节为单位 -->
<property name="maxUploadSize" value="1024000"></property>
</bean>
3、表单:POST请求,file类型,enctype="multipart/form-data"
表单:
<form action="${pageContext.request.contextPath }/fileUpload"
method="post" enctype="multipart/form-data">
text:<input type="text" name="text"><br> <br> 文件:<input
type="file" name="file"><br> <br> <input
type="submit" value="上传">
</form>
controller:
@RequestMapping(value = "/fileUpload")
public String fileUpload(HttpServletRequest request, @RequestParam(value = "text", required = false) String text,
@RequestParam("file") CommonsMultipartFile file) throws Exception {
String realPath = request.getServletContext().getRealPath("/upload");//获取真实路径
//System.out.println(realPath);
File file1 = new File(realPath);//创建文件夹
if (!file1.exists()) {
file1.mkdir();
}
OutputStream out = null;
InputStream in = null;//文件输入输出流
String prefix = UUID.randomUUID().toString();//生成唯一UUID
String fileName = prefix + "_" + file.getOriginalFilename();
System.out.println(fileName);
out = new FileOutputStream(new File(realPath + "\\" + fileName));
in = file.getInputStream();
// IOUtils.copy(in, out);//导入的jar自带的工具类,复制文件,下面是自己写的复制方法
int readIndex = 0;
int copyBytes = 0;
byte[] buffer = new byte[1024];
while ((readIndex = in.read(buffer)) > 0) {
out.write(buffer, 0, readIndex);
copyBytes += readIndex;
}
System.out.println("共复制了:" + copyBytes + "字节");
if (out != null)
out.close();
if (in != null)
in.close();//关闭流
return "success";
}
SpringMVC文件下载
@RequestMapping(value = "/goFileDownload")//转到下载页面,将文件名显示在页面上
public ModelAndView goFileDownload(HttpServletRequest request) throws Exception {
ModelAndView mv = new ModelAndView();
String path = request.getServletContext().getRealPath("/upload/");
System.out.println(path);
File file = new File(path);//获取目录
File[] files = file.listFiles();
List<String> fileName = new ArrayList<>();
for (int i = 0; i < files.length; i++)//获取文件名list
if (files[i].isFile())
fileName.add(files[i].getName());
mv.setViewName("download");
mv.addObject("files", fileName);
return mv;
}
@RequestMapping(value = "/fileDownload/{fileName:.+}")//接受文件名参数并下载对应文件,Spring下只需将返回值设置为ResponseEntity<byte[]>即可实现
public ResponseEntity<byte[]> fileDownload(HttpServletRequest request,
@PathVariable(value = "fileName") String fileName) throws Exception {
//System.out.println(fileName);
String path = request.getServletContext().getRealPath("/upload/" + fileName);//获取文件的真实路径
//System.out.println(path);
File file = new File(path);//创建文件对象,准备获取内容
InputStream in = new FileInputStream(file);
byte[] body = new byte[in.available()];
in.read(body);
if (in != null)
in.close();
HttpHeaders headers = new HttpHeaders();//设置响应头
fileName = new String(fileName.getBytes("gbk"), "iso8859-1");//防止中文文件名乱码,但是我去掉也能正常下载,可能是我的文件名是接收的原因
headers.add("Content-Disposition", "attachment;filename=" + fileName);
HttpStatus statusCode = HttpStatus.OK;//http状态码,此时为200 参考一篇博客
//System.out.println(statusCode);
ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(body, headers, statusCode);//设置返回值
return response;
}
Javaweb向服务器上传文件以及从服务器下载文件的方法的更多相关文章
- jQuery用FormData对象实现文件上传以及如何通过ajax下载文件
之前在Vue的项目里面用到过文件上传,封装好的组件用起来比较顺手,查询Element-UI文档,十八般武器样样都有,一顿操作猛如虎,一看--跑偏了(⊙o⊙)-,我的意思就是用框架实现比较简单,但是如果 ...
- FTP服务器上传工具,FTP服务器上传工具下载!
IIS7服务器管理工具能够作为FTP的客户端,进行FTP的命令操作,可在客户端,下载,安装FTP软件! 同时,它也可以作为VNC的客户端,进行VNC的命令操作!它能够批量连接Windows和Linux ...
- java使用JSCH连接FTP(Linux服务器)上传文件到Linux服务器
首先需要用到jsch-0.1.54.jar 包: 链接: https://pan.baidu.com/s/1kZR6MqwpCYht9Pp_D6NKQw 密码: gywx 直接上代码: package ...
- Javaweb学习笔记——上传下载文件
一.前言 在Javaweb中,上传下载是经常用到的功能,对于文件上传,浏览器在上传的过程中是以流的过程将文件传给服务器,一般都是使用commons-fileupload这个包实现上传功能,因为comm ...
- 使用批处理文件在FTP服务器 上传下载文件
1.从ftp服务器根目录文件夹下的文件到指定的文件夹下 格式:ftp -s:[配置文件] [ftp地址] 如:ftp -s:c:\vc\ftpconfig.txt 192.168.1.1 建立一个 ...
- 你知道哪些linux命令,能把文件上传到远程linux服务器
多数情况下 企业的服务基本都是部署在linux服务器 那对于测试同学,必须掌握基本的linux命令 至少要知道怎么部署整体环境 部署过程中,经常需要的操作,是向服务器上传部署包 你一般都是 ...
- 测试必备技能系列4:如何用SSH向linux服务器上传下载文件
通过ssh方式,向远程服务器上传文件 非常方便 直接看老徐之前的文章http://www.51testing.com/?uid-497177-action-viewspace-itemid-37054 ...
- ASP.NET跨服务器上传文件的相关解决方案
第一种:通过FTP来上传文件 首先,在另外一台服务器上设置好FTP服务,并创建好允许上传的用户和密码,然后,在ASP.NET里就可以直接将文件上传到这台 FTP 服务器上了.代码如下: <%@ ...
- 将本地文件上传到指定的服务器(HttpWebRequest方法)
将本地文件上传到指定的服务器(HttpWebRequest方法),通过文件流,带文件名,同文件一同上传的表单文本域及值. ///<summary> /// 将本地文件上传到指定的服务器(H ...
- JavaScript进阶(九)JS实现本地文件上传至阿里云服务器
JS实现本地文件上传至阿里云服务器 前言 在前面的博客< JavaScript进阶(八)JS实现图片预览并导入服务器功能>(点击查看详情)中,实现了JS将本地图片文件预览并上传至阿里云服务 ...
随机推荐
- css3-transition过渡属性
transition主要是用于一个元素的一种状态到另一种状态的一个过渡的过程,不能够主动触发,必须依赖于事件,例如hover伪类选择器. 一,transition简写 transition:要过渡的属 ...
- FTP publisher plugin插件
说明:这个插件可以将构建的产物(例如:Jar)发布到FTP中去. 官方说明:FTP publisher plugin 安装步骤: 系统管理→管理插件→可选插件→Artifact Uploaders→F ...
- 基于jmeter,jenkins,ANT接口,性能测试框架
背景 公司计划推接口和性能测试,搭建这个性能测试框架框架是希望能够让每个人(开发人员.测试人员)都能快速的进行性能,接口测试,而不需要关注性能测试环境搭建过程.因为,往往配置一个性能环境可能需要很长的 ...
- 【科普】什么是TLS1.3
TLS1.3是一种新的加密协议,它既能提高各地互联网用户的访问速度,又能增强安全性. 我们在访问许多网页的时候,常常会在浏览器的地址栏上看到一个锁的图标,并使用"https"代替传 ...
- 【grunt】grunt 基础学习
1. 干啥的呢? 项目打包管理,用处有 1)可用于压缩合并前端文件,包括css/js , 2)可用于管理发布文件与开发文件,3)可用于自动编译less 文件 2. 常用的东西有哪些呢? 常用的插件有 ...
- windows下配置cygwin和dig的环境变量
配置cygwin和dig的环境变量 打开"控制面板"("开始">"设置">"控制面板"),然后双击" ...
- HTMl课堂随笔
html: 1.超文本标记语言(Hyper Text Markup Lan) 2.不是一种编程语言,而是一种标记语言(Markup Language) 3.标记语言是一套标记标签(Markup Tag ...
- Linux 系统下安装 rz/sz 命令及使用说明
Linux 系统下安装 rz/sz 命令及使用说明 rz/sz命令,实现将本地的文件上传到服务器或者从服务器上下载文件到本地,但是很多Linux系统初始并没有这两个命令,以下为安装和使用的具体步骤: ...
- Python 文件的处理
简单的读取文件 f.read() 是读取这个文件的所有内容 f.readline() 是读取文件的一行 .write() 会去检查这个文件是否存在,不存在则创建,存在的话,则以覆盖的方式将内容写 ...
- JavaScript中数组的方法总结
js数组元素的添加和删除一直比较迷惑,今天终于找到详细说明的资料了,先给个我测试的代码^-^var arr = new Array();arr[0] = "aaa";arr[1] ...