背景:

http://www.cnblogs.com/lixuwu/p/8495275.html已经实现了单文件的上传和下载,多文件的上传是另一种情景,这里记录下来

实现过程

先说前台. 运行以后就是这样子的. 一个非常简单的表单页面, 两个文件上传按钮, 一个提交

其中单个文件上传, 即只能选择一个文件, 无法同时选择多个

相对的, 多个文件就是可以同时选择多个文件了

文件选择以后就是这个样子

前台设置

代码如下: 一个form, 文件上传就是一个<input>输入, 属性type="file". 此时只能选择单个文件. 而后面加一个multiple, 即可同时选择多个文件

jsp页面multiFile.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/test/upload" enctype="multipart/form-data" method="post">
单个文件: <input type="file" name="fileTest"><br/>
多个文件: <input type="file" name="fileList" multiple/></br/>
<input type="submit" value="提交" />
</form>
</body>
</html>

spring中文件控制bean:

package spring.boot.uploadfile.config;

import javax.servlet.MultipartConfigElement;

import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource; /**
* ClassName:ConfigClass <br/>
* Function: TODO <br/>
* Date: 2018年3月2日 下午8:20:05 <br/>
* @author prd-lxw
* @version 1.0
* @since JDK 1.7
* @see
*/
/**
* classpath路径:locations={"classpath:application-bean1.xml","classpath:application-bean2.xml"}
* file路径: locations = {"file:d:/test/application-bean1.xml"};
*/
@Configuration
@ImportResource(locations = { "classpath:spring-web.xml" })
//@ImportResource(locations={"file:d:/test/application-bean1.xml"})
public class ConfigClass { @Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
//文件最大
factory.setMaxFileSize("1000240KB"); //KB,MB
/// 设置总上传数据总大小
factory.setMaxRequestSize("102400KB");
return factory.createMultipartConfig();
} }

后台代码

Controller层代码:

/**
* Project Name:uploadfile
* File Name:MutilFileUploadController.java
* Package Name:spring.boot.uploadfile.controller
* Date:2018年3月2日下午9:50:25
* Copyright (c) 2018, 深圳金融电子结算中心 All Rights Reserved.
*
*/ package spring.boot.uploadfile.controller; import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest; /**
* ClassName:MutilFileUploadController <br/>
* Function: TODO <br/>
* Date: 2018年3月2日 下午9:50:25 <br/>
* @author prd-lxw
* @version 1.0
* @since JDK 1.7
* @see
*/
/**
* 文件上传测试类
*/
@Controller
@RequestMapping("/test")
public class MutilFileUploadController {
@RequestMapping("multi")
public String multiIndex() {
return "multiFile";
} @ResponseBody
@RequestMapping(value = "upload")
public void testUpload(MultipartHttpServletRequest request) throws IOException {
/*
* MultipartHttpServletRequest: 继承于HttpServletRequest以及MultipartRequest.
* 其中MultipartRequest中定义了相关的访问操作. MultipartHttpServletRequest重写
* 了HttpServletRequest中的方法, 并进行了扩展. 如果以HttpServletRequest来接收参
* 数, 则需要先将其转为MultipartHttpServletRequest类型
* MultipartHttpServletRequest request = (MultipartHttpServletRequest) HttpServletRequest;
*/ /*
* 再说回刚才的form, 假设我们在单个文件选框中上传了文件1, 多个文件选框中上传了文件2, 3, 4.
* 那么对于后台接收到的, 可以这么理解, 就是一个Map的形式(实际上它后台真的是以Map来存储的).
* 这个Map的Key是什么呢? 就是上面<input>标签中的name=""属性. Value则是我们刚才上传的
* 文件, 通过下面的示例可以看出每一个Value就是一个包含对应文件集合的List
*
* 传到后台接收到的Map就是这样:
* fileTest: 文件1
* fileList: 文件2, 文件3, 文件4
*
* 虽然从方法名的表面意义来看是得到文件名, 但实际上这个文件名跟上传的文件本身并没有什么关系.
* 刚才说了这个Map的Key就是<input>标签中的name=""属性, 所以得到的也就是这个属性的值
*/
Iterator<String> fileNames = request.getFileNames(); while (fileNames.hasNext()) { //把fileNames集合中的值打出来
String fileName = fileNames.next();
System.out.println("fileName: " + fileName); /*
* request.getFiles(fileName)方法即通过fileName这个Key, 得到对应的文件
* 集合列表. 只是在这个Map中, 文件被包装成MultipartFile类型
*/
List<MultipartFile> fileList = request.getFiles(fileName); if (fileList.size() > 0) { //遍历文件列表
Iterator<MultipartFile> fileIte = fileList.iterator(); while (fileIte.hasNext()) { //获得每一个文件
MultipartFile multipartFile = fileIte.next(); //获得原文件名
String originalFilename = multipartFile.getOriginalFilename();
System.out.println("originalFilename: " + originalFilename); //设置保存路径.
String path = "E:\\testJava\\filesss"; //检查该路径对应的目录是否存在. 如果不存在则创建目录
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
} String filePath = path + File.separator + originalFilename;
System.out.println("filePath: " + filePath); //保存文件
File dest = new File(filePath);
if (!(dest.exists())) {
/*
* MultipartFile提供了void transferTo(File dest)方法,
* 将获取到的文件以File形式传输至指定路径.
*/
multipartFile.transferTo(dest); /*
* 如果需对文件进行其他操作, MultipartFile也提供了
* InputStream getInputStream()方法获取文件的输入流
*
* 例如下面的语句即为通过
* org.apache.commons.io.FileUtils提供的
* void copyInputStreamToFile(InputStream source, File destination)
* 方法, 获取输入流后将其保存至指定路径
*/
//FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), dest);
} //MultipartFile也提供了其他一些方法, 用来获取文件的部分属性 //获取文件contentType
String contentType = multipartFile.getContentType();
System.out.println("contentType: " + contentType); /*
* 获取name
* 其实这个name跟上面提到的getFileName值是一样的,
* 就是Map中Key的值. 即前台页面<input>中name=""
* 属性. 但是上面的getFileName只是得到这个Map的Key,
* 而Spring在处理上传文件的时候会把这个值以name属性
* 记录到对应的每一个文件. 如果需要从文件层面获取这个
* 值, 则可以使用该方法
*/
String name = multipartFile.getName();
System.out.println("name: " + name); //获取文件大小, 单位为字节
long size = multipartFile.getSize();
System.out.println("size: " + size); System.out.println("---------------------------------------------------");
}
}
}
}
}

ps:上面的注释很简单,对照着实现就可以了

(转)Spring文件上传,包括一次选中多个文件的更多相关文章

  1. [转]ExtJs入门之filefield:文件上传的配置+结合Ajax完美实现文件上传的asp.net示例

    原文地址:http://www.stepday.com/topic/?459 作文一个ExtJs的入门汉子,学习起来的确是比较费劲的事情,不过如今在这样一个网络资源如此丰富的时代,依然不是那么难了的. ...

  2. 表单多文件上传样式美化 && 支持选中文件后删除相关项

    开发中会经常涉及到文件上传的需求,根据业务不同的需求,有不同的文件上传情况. 有简单的单文件上传,有多文件上传,因浏览器原生的文件上传样式及功能的支持度不算太高,很多时候我们会对样式进行美化,对功能进 ...

  3. 【Java EE 学习 22 上】【文件上传】【目录打散】【文件重命名】

    1.文件上传概述 (1)使用<input type="file">的方式来声明一个文件域. (2)表单提交方式一定要是post方式才行 (3)表单属性enctype 默 ...

  4. AJAX文件上传实践与分析,带HTML5文件上传API。

    对于HTML5已经支持AJAX文件上传了,但如果需要兼容的话还是得用一点小技巧的,HTML5等等介绍,先来看看以前我们是怎么写的. 网上可能会有一些叫AJAX文件上传插件,但在AJAX2.0之前是不可 ...

  5. [原创]java WEB学习笔记49:文件上传基础,基于表单的文件上传,使用fileuoload 组件

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  6. Angular14 利用Angular2实现文件上传的前端、利用springBoot实现文件上传的后台、跨域问题

    一.angular2实现文件上传前端 Angular2使用ng2-file-upload上传文件,Angular2中有两个比较好用的上传文件的第三方库,一个是ng2-file-upload,一个是ng ...

  7. springboot 文件上传及java使用post请求模拟文件上传

    参考自:https://blog.csdn.net/qq_25958999/article/details/83988974 接收端Controller类中方法: @RequestMapping(va ...

  8. NetCore文件上传校验返回未授权401,文件仍然执行上传操作,要如何解决呢

    这是代码:https://files.cnblogs.com/files/suterfo/NetCoreTestPro.rar 运行步骤: 一.使用Visual Studio2017打开项目,并F5运 ...

  9. 改变FileUpload文件上传控件的显示方式,选择文件后自动上传

    一.Aspx页面: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="File ...

随机推荐

  1. Python - 列表解析式

    列表解析——用来动态地创建列表 [expr for iter_var in iterable if cond_expr] 例子一: map(lambda x: x**2, range(6)) [0, ...

  2. Net-SNMP V3协议 安装配置笔记(CentOS 6.3/5.6)

    注意:snmp V3,需要需要关闭selinux和防火墙: 关闭selinux方法: #vi /etc/selinux/config 将文件中的SELINUX="" 为 disab ...

  3. git体会

    刘仙臣个人github链接:http://www.github.com/liuxianchen 这次作业学会了关于git的一些基本操作,学习了到了许多东西,为以后的学习奠定了基础,激发了学习的兴趣.具 ...

  4. Ping命令的另一种使用方法

    今天实习结束休息的时候无聊,于是便想看看机房有多少机器,IP是什么,有没有什么小漏洞. 依次使用了netstat.ping.Telnet以后,不小心输入了这样一个东西 当时按下回车以后,心里想的是这样 ...

  5. php开发APP接口(总结一)

    一.什么是app接口:服务端与客户端的数据交互. 大部分APP接口是通过http协议通信的. http通信的三要素: URL:   通信的地址 Method:通信的方式(get | post | pu ...

  6. PP-物料清单用户处理手册

    1 系统操作时间 1. 新旧物料的替换需有BOM的产生2. BOM中组件发生变化时需有BOM的更改2 系统操作权限角色编码 角色名称Z:PP_PS_007_1000_200 PP主数据维护员 3 适应 ...

  7. HTTP消息头(HTTP headers)-常用的HTTP请求头与响应头

    HTTP消息头是指,在超文本传输协议( Hypertext Transfer Protocol ,HTTP)的请求和响应消息中,协议头部分的那些组件.HTTP消息头用来准确描述正在获取的资源.服务器或 ...

  8. pxe+kickstart 自动化部署linux操作系统

    kickstart 是什么? 批量部署Linux服务器操作系统 运行模式: C/S client/server 服务器上要部署: DHCP tftp(非交互式文件共享) 安装系统的三个步骤: 1.加载 ...

  9. sql语句中日期相减的操作

    select datediff(year, 开始日期,结束日期); --两日期间隔年select datediff(quarter, 开始日期,结束日期); --两日期间隔季select datedi ...

  10. java.util.concuttent Callable Future详解

    在传统的多线程实现方式中(继承Thread和实现Runnable)无法直接获取线程执行的返回结果,如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦. 从 ...