java实现大文件上传和下载
【文件上传和下载】是很多系统必备功能, 比如PM\OA\ERP等;系统中常见的开发模式有B/S和C/S,而前者主要是通过浏览器来访问web服务器,一般采用七层协议中的【应用层http】进行数据传输,后者主要通过编程语言开发的app作为客户端来访问服务端,一般采用七层协议中的【传输层tcp】进行数据传输。
文章主要完成简单java web涉及的文件上传和下载功能。
正文
1. java原生servlet实现:
pom.xml配置:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.</version>
<scope>runtime</scope>
</dependency>
web.xml配置:
<welcome-file-list>
<welcome-file>/WEB-INF/view/jsp/upload/upload.jsp</welcome-file>
</welcome-file-list>
<!-- 声明Servlet对象 -->
<servlet>
<!-- 指定Servlet对象的名称 -->
<servlet-name>UploadServlet</servlet-name>
<!-- 指定Servlet对象的完整位置,包含包名和类名 -->
<servlet-class>pers.chaffee.servlet.UploadServlet</servlet-class>
</servlet>
<!-- 映射Servlet -->
<servlet-mapping>
<!--<servlet-name>与上面<Servlet>标签的<servlet-name>元素相对应,不可以随便起名 -->
<servlet-name>UploadServlet</servlet-name>
<!-- 用于映射访问URL -->
<url-pattern>/UploadFileServlet</url-pattern>
</servlet-mapping>
servlet实现:
@WebServlet("/UploadServlet")
public class UploadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
//根据文件扩展名设置文件MIME类型
resp.setContentType(getServletContext().getMimeType("hello.txt"));
//设置下载消息响应,提示文件保存attachment
resp.setHeader("Content-Disposition", "attachment;filename=" + "hello");
/*
* 设置缓冲区
* is.read(b)当文件读完时返回-1
*/
try {
//输入流为项目文件,输出流指向浏览器
InputStream is = new FileInputStream("E:\\hello.txt");
// 提供了将二进制数据写入响应的流
ServletOutputStream os = resp.getOutputStream();
int len = -1;
byte[] b = new byte[1024];
while ((len = is.read(b)) != -1) {
os.write(b, 0, len);
}
//关闭流
is.close();
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
// 文件上传到本地磁盘工厂类
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置内存缓冲区的大小
factory.setSizeThreshold(20480);
//设置临时文件目录,供上传文件过大时临时存储
factory.setRepository(new File("F:\\f"));
//文件上传操作核心类
ServletFileUpload upload = new ServletFileUpload(factory);
//设置限制单个上传文件的大小
upload.setFileSizeMax(50480);
//设置限制总上传文件大小
upload.setSizeMax(80480);
// 这个路径相对当前应用的目录
try {
List<FileItem> formItems = upload.parseRequest(req);
if (formItems != null && formItems.size() > 0) {
// 迭代表单数据
for (FileItem item : formItems) {
// 处理不在表单中的字段
if (!item.isFormField()) {
File storeFile = new File("F:\\fromweb_" + item.getName());
// 保存文件到硬盘
item.write(storeFile);
}
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
upload.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>文件上传实例</h1>
<!--请求编码类型必须为"multipart/form-data"-->
<form method="post" action="/UploadFileServlet" enctype="multipart/form-data">
选择一个文件:
<input type="file" name="uploadFile"/>
<input type="file" name="uploadFile2"/>
<br/><br/>
<input type="submit" value="上传"/>
</form>
<a href="/UploadFileServlet" rel="nofollow">下载</a>
</body>
</html>
2. java web主流框架【ssm】实现:
pom.xml配置
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
web.xml配置
<context-param>
<param-name>contextConfigLocation</param-name>
<!--<param-value>classpath*:applicationContext-*.xml</param-value>-->
<param-value>classpath*:*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
spring-mvc.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- 启动SpringMVC的注解功能 -->
<mvc:annotation-driven/>
<!-- 扫描controller(controller层注入) -->
<context:component-scan base-package="pers.chaffee.controller"/>
<!-- 对模型视图添加前后缀 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/view/jsp/" p:suffix=".jsp"/>
<!-- 静态资源不走controller -->
<mvc:resources mapping="/resources/**" location="/resources/"/>
</beans>
servlet实现:
@RequestMapping(value = "/upload2", method = RequestMethod.POST, consumes = {"multipart/form-data"})
public ModelAndView postUpload(HttpServletRequest request, HttpServletResponse response) {
//文件上传核心类
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
//判断request是否有文件上传
if (multipartResolver.isMultipart(request)) {
//通过MultipartHttpServletRequest解析上传请求中的文件
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
//获取上传请求中的所有文件
Iterator<String> iter = multiRequest.getFileNames();
while (iter.hasNext()) {
//转换成spring支持的文件类型MultipartFile
MultipartFile file = multiRequest.getFile(iter.next());
if (file != null) {
File localFile = new File("F:\\f\\" + file.getOriginalFilename());
try {
//将上传文件写到指定位置,此处是本地文件夹
file.transferTo(localFile);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("upload/upload2");
return modelAndView;
}
@RequestMapping(value = "/download", method = RequestMethod.GET)
public ResponseEntity<byte[]> downLoad() throws IOException {
byte[] responseBody;
//获取文件
File file = new File("E:\\hello.txt");
InputStream is = new FileInputStream(file);
responseBody = new byte[is.available()];
is.read(responseBody);
HttpHeaders headers = new HttpHeaders();
//设置文件类型
headers.add("Content-Disposition", "attachment;filename=" + file.getName());
//设置Http状态码
HttpStatus stateCode = HttpStatus.OK;
//返回数据
ResponseEntity<byte[]> entity = new ResponseEntity<>(responseBody, headers, stateCode);
return entity;
}
小结
截至目前,只初步完成B/S方式的上传和下载,且文件存储方式仅限本地磁盘。而C/S方式的文件传输可以考虑thrift框架,thrift是一种跨平台跨语言的RPC框架,使用过程中发现在数据量不是很大的情况下thrift应用是一种比较合适的C/S解决方案;另外,文件存储方式可以根据具体情况选用文件服务器、数据库等。
详细的配置信息可以参考这篇文章:
java实现大文件上传和下载的更多相关文章
- java+web+大文件上传下载
文件上传是最古老的互联网操作之一,20多年来几乎没有怎么变化,还是操作麻烦.缺乏交互.用户体验差. 一.前端代码 英国程序员Remy Sharp总结了这些新的接口 ,本文在他的基础之上,讨论在前端采用 ...
- 【原创】用JAVA实现大文件上传及显示进度信息
用JAVA实现大文件上传及显示进度信息 ---解析HTTP MultiPart协议 (本文提供全部源码下载,请访问 https://github.com/grayprince/UploadBigFil ...
- Nginx集群之WCF大文件上传及下载(支持6G传输)
目录 1 大概思路... 1 2 Nginx集群之WCF大文件上传及下载... 1 3 BasicHttpBinding相关配置解析... 2 4 编写 ...
- 全网最简单的大文件上传与下载代码实现(React+Go)
前言 前段时间我需要实现大文件上传的需求,在网上查找了很多资料,并且也发现已经有很多优秀的博客讲了大文件上传下载这个功能. 我的项目是个比较简单的项目,并没有采用特别复杂的实现方式,所以我这篇文章的目 ...
- Java实现FTP文件上传与下载
实现FTP文件上传与下载可以通过以下两种种方式实现(不知道还有没有其他方式),分别为:1.通过JDK自带的API实现:2.通过Apache提供的API是实现. 第一种方式 package com.cl ...
- 用JAVA实现大文件上传及显示进度信息
一. 大文件上传基础描述: 各种WEB框架中,对于浏览器上传文件的请求,都有自己的处理对象负责对Http MultiPart协议内容进行解析,并供开发人员调用请求的表单内容. 比如: Spring 框 ...
- 【Java】JavaWeb文件上传和下载
文件上传和下载在web应用中非常普遍,要在jsp环境中实现文件上传功能是非常容易的,因为网上有许多用java开发的文件上传组件,本文以commons-fileupload组件为例,为jsp应用添加文件 ...
- java支持断点续传文件上传和下载组件
java两台服务器之间,大文件上传(续传),采用了Socket通信机制以及JavaIO流两个技术点,具体思路如下: 实现思路: 1.服:利用ServerSocket搭建服务器,开启相应端口,进行长连接 ...
- PHP实现大文件上传和下载
一提到大文件上传,首先想到的是啥??? 没错,就是修改php.ini文件里的上传限制,那就是upload_max_filesize.修改成合适参数我们就可以进行愉快的上传文件了.当然啦,这是一般情况下 ...
随机推荐
- rm 参数列表过长
刚摸索了一个小技巧,有时候在删除文件的时候,文件很多,直接用rm -rf * ,会报错误“rm 参数列表过长”. 这时候网上的办法一般都是通过类似的办法:find . -name "&quo ...
- git 去除版本控制
git会进入当前文件目录, 然后执行如下命令: find . -name ".git" | xargs rm -Rf 该项目就会去除git的版本控制了.再修改的话也不会影响git的 ...
- 一个炒鸡好用的pdf阅读器
下载地址:https://www.sumatrapdfreader.org/free-pdf-reader.html 一个关系很好的同事推荐的pdf阅读器 之前用的感觉不错 每次都记不住 自己收 ...
- Java BinarySearch
Java BinarySearch /** * <html> * <body> * <P> Copyright 1994-2018 JasonInternation ...
- C++虚函数【Java有虚函数吗?】
1,简单介绍 定义在基类中的函数,子类必须对其进行覆写![必须对其进行覆写?!]——Java中的接口.Abstract方法中的抽象类也有这样的要求. C++中定义: virtual void deal ...
- mysql cmd命令行 创建数据库 表 基础语句
一.连接MYSQL 格式: mysql -h主机地址 -u用户名 -p用户密码 1. 连接到本机上的MYSQL. 首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u roo ...
- 基于PhotoView的头像/圆形裁剪控件
常见的图片裁剪有两种,一种是图片固定,裁剪框移动放缩来确定裁剪区域,早期见的比较多,缺点在于不能直接预览裁剪后的效果:还有一种现在比较普遍了,就是裁剪框固定,直接拖动缩放图片,便于预览裁剪结果. 我做 ...
- Eigen 学习笔记
1. 初始化 //外部指针初始化 ]={...}; ] = ...; kernels[].mu = Vector3d(_mu0); kernels[].sigma_inv = Matrix3d(_s ...
- 【shell脚本】$ 在shell脚本中的使用
shell脚本中 '$' 与不同的符号搭配其表示的意义也会不同 特殊标志符 含义 $0 当前脚本的文件名 $n 传递给脚本或函数的参数.n 是一个数字,表示第几个参数. 例如,第一个参数是$1,第二个 ...
- 理解JVM之垃圾回收
1.垃圾收集算法 1) 标记-清楚算法:该算法是最基础的收集算法,其分为标记与清除两个阶段.首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象,该算法主要有两个不足:一个是效率问题,标 ...