1、文件上传

Spring MVC框架的文件上传是基于commons-fileupload组件的文件上传,只不过Spring MVC框架在原有文件上传组件上做了进一步封装,简化了文件上传的代码实现。

1.1、单文件上传

需要commons-fileupload组件相关依赖

<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>

页面中的form表单上添加多部件属性,fileupload.jsp

<form action="${pageContext.request.contextPath}/onefile" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="myfile"><br>
文件描述:<input type="text" name="description"><br>
<input type="submit" value="上传">
</form>

enctype属性指定的是表单数据的编码方式,该属性有以下3个值:

  • application/x-www-form-urlencoded:默认的编码方式,只处理表单域里的value属性值;
  • multipart/form-data:以二进制流的方式来处理表单数据,并将文件域指定文件的内容封装到请求参数里;
  • text/plain:只有当表单的action属性为mailto:URL的形式时才使用,主要适用于直接通过表单发送邮件的方式。

创建POJO实体类

import org.springframework.web.multipart.MultipartFile;

public class FileDomain {
private String description;
private MultipartFile myfile; //getter和setter
}

在实体类中声明MultipartFile类型的属性封装被上传的文件信息,属性名与文件上传页面fileupload.jsp中的file类型的表单参数名myfile相同。

创建控制器类

@Controller
public class FileUploadController { @RequestMapping("/onefile")
public String oneFileUpload(@ModelAttribute FileDomain fileDomain, HttpServletRequest request){
//文件上传的位置
String realpath = request.getServletContext().getRealPath("uploadfiles");
//上传文件的名称
String fileName = fileDomain.getMyfile().getOriginalFilename();
File targetFile = new File(realpath,fileName);
if(!targetFile.exists()){
targetFile.mkdirs();//创建目录
}
try {
fileDomain.getMyfile().transferTo(targetFile);
System.out.println("文件上传成功");
} catch (Exception e){
e.printStackTrace();
} return "showFile";
}
}

配置springmvc.xml

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

创建showFile.jsp用于展示结果:

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>文件上传信息</title>
</head>
<body>
文件名称:${fileDomain.myfile.originalFilename}<br>
文件描述:${fileDomain.description}
</body>
</html>

上传页面展示:

上传结果展示:

注意事项:

  • 在上传页面fileupload.jsp中,form表单一定要加enctype属性,值为multipart/form-data,表单提交方式设置为post;
  • form表单中的file标签的name属性要和实体类的MultipartFile属性的名称保持一致;
  • 要在springmvc.xml中使用CommonsMultipartResolver类配置multipartResolver用于文件上传;

1.2、多文件上传

创建multifiles.jsp文件上传页面:

<form action="${pageContext.request.contextPath}/multifile" method="post" enctype="multipart/form-data">
<p>
选择文件1:<input type="file" name="myfile"><br>
文件描述1:<input type="text" name="description">
</p>
<p>
选择文件2:<input type="file" name="myfile"><br>
文件描述2:<input type="text" name="description">
</p>
<p>
选择文件3:<input type="file" name="myfile"><br>
文件描述3:<input type="text" name="description">
</p>
<p>
<input type="submit" value="提交">
</p>
</form>

创建POJO类:

public class MultiFileDomain {
private List<String> description;
private List<MultipartFile> myfile;
//getter和setter
}

创建Controller类,接收上传参数:

@Controller
public class FileUploadController { //多文件上传
@RequestMapping("/multifile")
public String multiFileUpload(@ModelAttribute MultiFileDomain multiFileDomain,HttpServletRequest request){
String realpath = request.getServletContext().getRealPath("uploadfiles");
File targetDir = new File(realpath);
if(!targetDir.exists()){
targetDir.mkdirs();
}
List<MultipartFile> files = multiFileDomain.getMyfile();
for (int i=0;i<files.size();i++){
MultipartFile file = files.get(i);
String fileName = file.getOriginalFilename();
File targetFile = new File(realpath,fileName);
//上传
try {
file.transferTo(targetFile);
} catch (Exception e){
e.printStackTrace();
}
}
System.out.println("文件上传成功!");
return "showMulti";
}
}

创建成功信息页面showMulti.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>多文件上传结果</title>
</head>
<body>
<table width="50%" border="1">
<tr>
<td>文件名</td>
<td>详情</td>
</tr>
<c:forEach var="des" items="${multiFileDomain.description}" varStatus="loop">
<tr>
<td>${multiFileDomain.myfile[loop.count-1].originalFilename}</td>
<td>${des}</td>
</tr>
</c:forEach>
</table>
</body>
</html>

测试多文件上传

上传结果:

2、文件下载

2.1、文件下载相关介绍

实现文件下载有两种方法:一种是通过超链接实现下载,另一种是利用程序编码实现下载。通过超链接实现下载比较简单,但是会暴露下载文件的真实位置,利用程序编码实现下载可以增加安全访问控制。
利用程序实现下载需要设置两个报头:
(1)设置Content-Type的值为application/x-msdownload
这项设置主要是为了告诉浏览器,其所输出内容的类型不是普通文本文件或HTML文件,而是一个要保存到本地的下载文件。
(2)设置Content-Disposition的值为attachment,并且在后面指定filename参数
这项设置主要是让浏览器不要直接处理相应的实体内容,而是由用户选择将相应的实体内容保存到一个文件中。该报头指定了接收程序处理数据内容的方式,在HTTP应用中只有attachment是标准方式,attachment表示要求用户干预。在attachment后面还可以指定filename参数,该参数是服务器建议浏览器将实体内容保存到文件中的文件名称。
设置报头的示例代码如下:

//设置下载文件使用的报头
response.setHeader("Content-Type","application/x-msdownload");
response.setHeader("Content-Disposition","attachment;filename="+filename);

2.2、文件下载的功能实现

创建FileDownController类,并编写下载功能的方法:

@Controller
public class FileDownController { @RequestMapping("/down")
public String down(@RequestParam String filename, HttpServletRequest request, HttpServletResponse response){
String filePath = null; //要下载的文件路径
FileInputStream in = null; //输入流
ServletOutputStream out = null; //输出流
try {
//文件下载路径
filePath = request.getServletContext().getRealPath("uploadfiles");
//设置下载文件使用的报头
response.setHeader("Content-Type","application/x-msdownload");
response.setHeader("Content-Disposition","attachment;filename="+toUTF8String(filename));
//读入文件
in = new FileInputStream(filePath+"\\"+filename);
//得到响应对象的输出流,用于向客户端输出二进制数据
out = response.getOutputStream();
out.flush();
int aRead = 0;
byte[] b = new byte[1024];
while ((aRead=in.read(b))!=-1 && in!=null){
out.write(b,0,aRead);
}
out.flush();
in.close();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("下载成功!");
return null; } /**
* 下载保存时中文文件名的字符编码转换方法
*/
public String toUTF8String(String str){
StringBuffer sb = new StringBuffer();
int len = str.length();
for (int i=0;i<len;i++) {
//取出字符中的每个字符
char c = str.charAt(i);
//Unicode码值为0-255时,不做处理
if(c>=0 && c<=255){
sb.append(c);
}else{
//转换UTF-8编码
byte[] b;
try {
b = Character.toString(c).getBytes("UTF-8");
} catch (Exception e){
e.printStackTrace();
b = null;
}
//转换为%HH的字符串形式
for (int j=0;j<b.length;j++){
int k = b[j];
if(k<0){
k&=255;
}
sb.append("%"+Integer.toHexString(k).toUpperCase());
}
}
}
return sb.toString();
} }

创建页面展示可下载文件的Controller类和方法:

@RequestMapping("/show")
public String show(HttpServletRequest request, Model model){
//文件下载路径
String realPath = request.getServletContext().getRealPath("uploadfiles");
File dir = new File(realPath);
File[] files = dir.listFiles();
//获取该目录下的所有文件名
ArrayList<String> fileNames = new ArrayList<String>();
for (int i=0;i<files.length;i++) {
fileNames.add(files[i].getName());
}
model.addAttribute("files",fileNames);
return "showDown";
}

创建用于文件下载展示的showDown.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>文件下载</title>
</head>
<body> <table width="50%" border="1">
<tr>
<th>文件名</th>
<th>操作</th>
</tr>
<c:forEach var="filename" items="${files}">
<tr>
<td>${filename} </td>
<td>
<a href="${pageContext.request.contextPath}/down?filename=${filename}">下载</a>
</td>
</tr>
</c:forEach>
</table> </body>
</html>

效果展示:

点击下载链接

SpringMVC框架06——文件上传与下载的更多相关文章

  1. 使用SpringMVC框架实现文件上传和下载功能

    使用SpringMVC框架实现文件上传和下载功能 (一)单个文件上传 ①配置文件上传解释器 <!—配置文件上传解释器 --> <mvc:annotation-driven>&l ...

  2. SpringMVC(4):文件上传与下载

    一,文件上传 文件上传是项目开发中最常见的功能之一 ,springMVC 可以很好的支持文件上传,但是SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理 ...

  3. ExtJS+SpringMVC文件上传与下载

    说到文件上传.下载功能,网络上大多介绍的是采用JSP.SpringMVC或者Struts等开源框架的功能,通过配置达到文件上传.下载的目地.可是最近项目要用到文件上传与下载的功能,因为本项目框架采用开 ...

  4. 学习SpringMVC必知必会(7)~springmvc的数据校验、表单标签、文件上传和下载

    输入校验是 Web 开发任务之一,在 SpringMVC 中有两种方式可以实现,分别是使用 Spring 自带的验证 框架和使用 JSR 303 实现, 也称之为 spring-validator 和 ...

  5. springmvc和servlet在上传和下载文件(保持文件夹和存储数据库Blob两种方式)

    参与该项目的文件上传和下载.一旦struts2下完成,今天springmvc再来一遍.发现springmvc特别好包,基本上不具备的几行代码即可完成,下面的代码贴: FileUpAndDown.jsp ...

  6. SpringMVC 实现文件上传与下载,并配置异常页面

    目录 上传文件的表单要求 Spring MVC实现上传文件 需要导入的jar包 配置MultipartResolver解析器 编写接收上传文件的控制器 Spring MVC实现文件下载 下载文件时的h ...

  7. SpringMVC文件上传和下载的实现

    SpringMVC通过MultipartResolver(多部件解析器)对象实现对文件上传的支持. MultipartResolver是一个接口对象,需要通过它的实现类CommonsMultipart ...

  8. java:struts框架3(自定义拦截器,token令牌,文件上传和下载(单/多))

    1.自定义拦截器: struts.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ...

  9. layUI框架中文件上传前后端交互及遇到的相关问题

    下面我将讲述一下我在使用layUI框架中文件上传所遇到的问题: 前端jsp页面: <div class="layui-form-item"> <label cla ...

随机推荐

  1. 【CF884D】Boxes And Balls k叉哈夫曼树

    题目大意:给定一个大小为 N 的集合,每次可以从中挑出 2 个或 3 个数进行合并,合并的代价是几个数的权值和,求将这些数合并成 1 个的最小代价是多少. 引理:K 叉哈夫曼树需要保证 \((n-1) ...

  2. 线段树区间更新 lazy

    1. hdu1698 http://acm.hdu.edu.cn/showproblem.php?pid=1698 /* x y k x~y的值变为k */ #include <cstdio&g ...

  3. libvirt工具实现虚拟机管理

    libvirt工具实现虚拟机管理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.介绍virt-install命令的常用参数 virt-install是一个命令行工具,它能够为K ...

  4. Apache 与 Tomcat 整合

    目标 1.同一台机器上,不同的域名指向,访问不同的项目,即: (1)one.test.com 访问 project_one (2) two.test.com 访问 project_two   2.将T ...

  5. vue-router 编程式导航

    借助vue-router的实例方法,通过编写代码来实现导航的切换: back:回退一步 forward:前进一步 go:指定前进回退步数 push:导航到不同url,向history栈添加一个新的记录 ...

  6. Asp.Net中索引器的用法

    索引器定义类似于属性,但其功能与属性并不相同.索引器提供一种特殊的方法编写get和set访问器.属性可以像访问字段一样访问对象的数据,索引器可以使用户像访问数组一样访问类成员. 一.索引器特性 1.g ...

  7. python中的__call__

    如果python中的一个类定义了 __call__ 方法,那么这个类它的实例就可以作为函数调用,也就是实现了 () 运算符,即可调用对象协议 下面是一个简单的例子: class TmpTest: de ...

  8. sync 解释

    sync命令用于强制被改变的内容立刻写入磁盘,更新超块信息. 在Linux/Unix系统中,在文件或数据处理过程中一般先放到内存缓冲区中,等到适当的时候再写入磁盘,以提高系统的运行效率.sync命令则 ...

  9. LCT摘要

    介绍.用途 LCT是树链剖分中的一种,又叫实链剖分.动态树,常用于维护动态的树.森林. 维护方式 LCT并不直接维护原树,而是用一堆splay作为辅助树来维护.原树中的一条实链上的点在一棵splay中 ...

  10. 小白学习安全测试(四)——扫描工具-Vega

    WEB扫描工具-Vega 纯图形化界面,Java编写的开源web扫描器.两种工作模式:扫描模式和代理模式[主流扫描功能].用于爬站.处理表单,注入测试等.支持SSL:http://vega/ca.cr ...