首页 > 其他分享 >SpringMVC的单文件上传,多文件上传和下载文件(十二)

SpringMVC的单文件上传,多文件上传和下载文件(十二)

时间:2022-11-10 15:35:21浏览次数:36  
标签:文件 String SpringMVC user file message 上传


你未看此花时,则此花与汝心同归于寂, 你来看此花时,此花颜色一时明白起来,便知此花不在你的心外。
上一章简单介绍了SpringMVC的数据验证和JSR 303国际化显示(十一),如果没有看过,​​请观看上一章​​。

一. SpringMVC的文件上传和下载

文件上传和下载功能是非常常用的,如上传用户的头像和上传文档等。 可以结合老蝴蝶以前写的文章Struts2的文件上传功能来结合性学习:​​Struts2实现单文件上传,多文件上传与下载(十)​​

SpringMVC在实现上传的时候,主要依赖于 org.springframework.web.multipart.MultipartFile 接口。

其接口定义为:

public abstract interface MultipartFile
extends InputStreamSource
{
public abstract String getName();

public abstract String getOriginalFilename();

public abstract String getContentType();

public abstract boolean isEmpty();

public abstract long getSize();

public abstract byte[] getBytes()
throws IOException;

public abstract InputStream getInputStream()
throws IOException;

public abstract void transferTo(File paramFile)
throws IOException, IllegalStateException;
}

其中,主要使用的是 getOriginalFilename()和 transferTo() 方法。 前者是获取 上传文件的名称,后者是进行文件的复制。

MultipartFile 接口的实现类是: org.springframework.web.multipart.commons.CommonsMultipartFile

这个类也与Struts2一样,同样需要依赖于apache 提供的文件上传jar包。

commons-fileupload-1.3.1.jar,commons-io-2.4.jar

SpringMVC的单文件上传,多文件上传和下载文件(十二)_SpringMVC下载文件

SpringMVC在上传文件的时候,可以将其放置在方法里面,单独使用,也可以将其与相应的对象类进行关联使用。 通常选用第二种方式。

也同样是简单的User 类。 比以前多添加了一个 image 属性,来进行上传。
所拥有的属性有: (为节省篇福,避免出现像前几章那样长的坏文章形式,老蝴蝶就不贴完整的代码了。抱歉。)

private Integer id;
private String name;
private String sex;
private Integer age;
private String descrption;

//有一个上传图片的路径的属性

private String image;

均需要导入 上面那两个jar包。 不要忘记噢

SpringMVC的单文件上传,多文件上传和下载文件(十二)_SpringMVC下载文件

二. SpringMVC实现单文件上传,方法内参数形式

二.一 前端界面1 login.jsp ,上传文件

要注意, 提交的方法类型为post, enctype类型为 multipart/form-data

用的是普通的 type=file 框,并没有form:file 标签。

<body>
<h2>两个蝴蝶飞,文件上传使用</h2>
<form:form commandName="user" action="login.action"
enctype="multipart/form-data" type="post">
<form:label path="name">姓名:</form:label>
<form:input path="name"/> <br/><br/>

<input type="file" name="file"> <br/><br/>

<form:button>提交</form:button>
</form:form>
</body>

二.二 前端界面2 list.jsp,展示文件

<body>
你好,${message} <img src="${pageContext.request.contextPath}${user.image}" width=100 height=100>
</body>

二.三 后端处理, UserAction

//转到登录的页面
@RequestMapping(value="toLogin")
public String toLogin(Model model){
model.addAttribute("user",new User());
return "user/login";
}
//绑定到user对象。 value="file" 要与form表单的file框的name相同.
@RequestMapping(value="login")
public String login(User user,Model model,HttpServletRequest request,
@RequestParam(value="file") MultipartFile file){
System.out.println("输出名称:"+user.getName());
System.out.println("输出MultipartFile接口中的各个方法的值");
System.out.println("contentType:"+file.getContentType());
System.out.println("name:"+file.getName());
System.out.println("originalFilename:"+file.getOriginalFilename());
System.out.println("size:"+file.getSize());
String message="";
//进行上传文件
if(!file.isEmpty()){ //不为空,即上传了文件
//1. 获取服务器的文件
String path=request.getServletContext().getRealPath("/upload");
//2. 获取上传的文件的名称
String fileName=file.getOriginalFilename();
//3. 实例化构建文件。
File filePath=new File(path,fileName);
//4.判断文件,如果父不存在的话,即upload文件夹不存在的话,就创建父级文件夹。
if(!filePath.getParentFile().exists()){
filePath.getParentFile().mkdirs();
}

try {
file.transferTo(new File(path+File.separator+fileName));
message="文件上传成功";
//设置上传的路径,这里手动设置
user.setImage("/upload"+"/"+fileName);
System.out.println("输出图片路径:"+user.getImage());
} catch (IllegalStateException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
message="文件上传失败";
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
message="文件上传失败";
}
}else{
message="没有上传文件";
}
model.addAttribute("user",user);
model.addAttribute("message",message);
return "user/list";
}

二.四 springmvc.xml 配置文件中配置文件上传的 CommonsMultipartResolver

在 <mvc:annotation-driven></mvc:annotation-driven> 里面,并没有默认提供关于文件上传的解析器。
需要单独添加

<mvc:annotation-driven></mvc:annotation-driven>
<!-- 添加文件上传所用的bean -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上传文件大小上限,单位为字节(10MB) -->
<property name="maxUploadSize">
<value>10000000</value>
</property>
<!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->
<property name="defaultEncoding">
<value>UTF-8</value>
</property>
</bean>

二.五 重启服务器,进行验证

要上传的图片是:

SpringMVC的单文件上传,多文件上传和下载文件(十二)_SpringMVC的单文件上传_03

进行上传:

SpringMVC的单文件上传,多文件上传和下载文件(十二)_SpringMVC下载文件_04

上传成功,页面跳转展示:

SpringMVC的单文件上传,多文件上传和下载文件(十二)_SpringMVC的单文件上传_05

控制台打印输出:

SpringMVC的单文件上传,多文件上传和下载文件(十二)_上传_06

Tomcat 服务器上,upload 文件夹下有这个图片文件。

SpringMVC的单文件上传,多文件上传和下载文件(十二)_SpringMVC的单文件上传_07

文件上传成功。 相比较Struts2来说,非常非常简单。

三. SpringMVC实现单文件上传,与对象关联形式

并不是将 MultipartFile 放置在方法里面了,而是放置在User 对象里面。

三.一 User.java 中添加一个MultipartFile类型 的属性。

//定义属性为imageFile
private MultipartFile imageFile;

要实现setter 和getter的方法。

三.二 前端login.jsp 需要改变一下,将type=file的name改成 imageFile .

<form:form commandName="user" action="login.action"  
enctype="multipart/form-data" type="post">
<form:label path="name">姓名:</form:label>
<form:input path="name"/> <br/><br/>

<!--与user 类中的那个属性值对应-->
<input type="file" name="imageFile"> <br/><br/>

<form:button>提交</form:button>
</form:form>

list.jsp 保持不变。

三.三 后端 UserAction 需要改变一下,去除多余的输出

//转到登录的页面
@RequestMapping(value="toLogin")
public String toLogin(Model model){
model.addAttribute("user",new User());
return "user/login";
}
//绑定到user对象。
@RequestMapping(value="login")
public String login(User user,Model model,HttpServletRequest request){

String message="";
MultipartFile file=user.getImageFile();

/*后面这些都一样了*/
//进行上传文件
if(null!=file&&!file.isEmpty()){ //不为空,即上传了文件
//1. 获取服务器的文件
String path=request.getServletContext().getRealPath("/upload");
//2. 获取上传的文件的名称
String fileName=file.getOriginalFilename();
//3. 实例化构建文件。
File filePath=new File(path,fileName);
//4.判断文件,如果父不存在的话,即upload文件夹不存在的话,就创建父级文件夹。
if(!filePath.getParentFile().exists()){
filePath.getParentFile().mkdirs();
}
try {
file.transferTo(new File(path+File.separator+fileName));
//设置图片的路径。
user.setImage("/"+"upload"+"/"+fileName);
message="文件上传成功";
} catch (IllegalStateException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
message="文件上传失败";
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
message="文件上传失败";
}
}else{
message="没有上传文件";
}
model.addAttribute("user",user);
model.addAttribute("message",message);
return "user/list";
}

三.四 springmvc.xml 的配置与上面的一样,不需要改变

三.五 运行服务器,进行测试

用这张图片进行测试

SpringMVC的单文件上传,多文件上传和下载文件(十二)_文件上传_08

点击提交,运行成功,跳转到list.jsp页面。页面展示:

SpringMVC的单文件上传,多文件上传和下载文件(十二)_文件上传_09

哈哈,这猫,很形象啊。

四. 多文件上传及多文件列表展示, 与对象关联的形式

springmvc 也同样支持多文件上传, 需要把 MultipartFile 单对象改成 数组形式 MultipartFile [] 或者是集合形式 List ,习惯用数组形式来接收。

当然,也用两种用法,一个是方法参数,另外一个就是与对象关联, 这里用对象关联的形式进行讲解,顺便把 文件的展示列表也给讲了。

四.一 重新定义 User.java 类的属性

将image 变成 images, 并设置成集合的形式。 imageFile 变成imageFiles, 并且成为数组的形式。

//有多个上传图片的路径的属性
private List<String> images ;
//定义属性为imageFiles
private MultipartFile [] imageFiles;

老蝴蝶在这儿省略了 setter和getter方法。

四.二 上传文件的 login.jsp 页面

将单文件变成多文件

<body>
<h2>两个蝴蝶飞,文件上传使用</h2>
<form:form commandName="user" action="login.action"
enctype="multipart/form-data" type="post">
<form:label path="name">姓名:</form:label>
<form:input path="name"/> <br/><br/>
<!-- 可以使用js来动态设置,这里就指定为3个 -->
<input type="file" name="imageFiles"> <br/><br/>
<input type="file" name="imageFiles"> <br/><br/>
<input type="file" name="imageFiles"> <br/><br/>

<form:button>提交</form:button>
</form:form>
</body>

四.三 展示文件的 list.jsp页面

要展示多个, 用c:forEach 标签

不要忘记添加 jstl的core标签

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

页面展示:

<body>
你好,${message}<br/>

<c:forEach items="${user.images}" var="imgPath">
<img src="${pageContext.request.contextPath}${imgPath}" width=100 height=100> <br/>
</c:forEach>

</body>

四.四 后端UserAction 的处理

//转到登录的页面
@RequestMapping(value="toLogin")
public String toLogin(Model model){
model.addAttribute("user",new User());
return "user/login";
}
//绑定到user对象。
@RequestMapping(value="login")
public String login(User user,Model model,HttpServletRequest request){

String message="";
MultipartFile[] files=user.getImageFiles();

if(files!=null&&files.length>0){
List<String> images=new ArrayList<String>();
for(MultipartFile file:files){
//进行单个文件的判断。
if(file!=null&&!file.isEmpty()){ //不为空,即上传了文件
//1. 获取服务器的文件
String path=request.getServletContext().getRealPath("/upload");
//2. 获取上传的文件的名称
String fileName=file.getOriginalFilename();
//3. 实例化构建文件。
File filePath=new File(path,fileName);
//4.判断文件,如果父不存在的话,即upload文件夹不存在的话,就创建父级文件夹。
if(!filePath.getParentFile().exists()){
filePath.getParentFile().mkdirs();
}
try {
file.transferTo(new File(path+File.separator+fileName));
//设置图片的路径。
String imageName="/upload"+"/"+fileName;
images.add(imageName);
message="文件上传成功";
} catch (IllegalStateException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
message="文件上传失败";
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
message="文件上传失败";
}
}
//for 遍历之后,再设置
user.setImages(images);
}
}else{
message="没有上传文件";
}
model.addAttribute("user",user);
model.addAttribute("message",message);
return "user/list";
}

四.五 springmvc.xml 配置文件,不需要 改变

四.六 运行服务器,进行测试

上传提交:

SpringMVC的单文件上传,多文件上传和下载文件(十二)_SpringMVC的多文件上传_10

提交后,展示图片

SpringMVC的单文件上传,多文件上传和下载文件(十二)_文件上传_11

Tomcat服务器 路径显示:

SpringMVC的单文件上传,多文件上传和下载文件(十二)_SpringMVC的多文件上传_12

多文件上传成功。

五. 下载文件

众所皆知, 链接到正确的位置,可以进行下载。 下面,用a 链接看看。

五.一 a 链接显示

将多文件列表那个 list.jsp 的显示图片 <img> ,改成 <a> 链接的话,看看效果怎么样。

<body>
你好,${message}<br/>
<ul style="list-style: none;">
<c:forEach items="${user.images}" var="imgPath">
<%-- <img src="${pageContext.request.contextPath}${imgPath}" width=100 height=100> <br/> --%>
<li>
<a href="${pageContext.request.contextPath}${imgPath}">${imgPath}</a>
</li>
</c:forEach>
</ul>
</body>

刷新后展示为:

SpringMVC的单文件上传,多文件上传和下载文件(十二)_上传_13

点击链接,发现会进行查看,并不会下载。

SpringMVC的单文件上传,多文件上传和下载文件(十二)_文件上传_14

用JS 强行下载呢?

五.二 JS 强制 a链接下载

将上面 的 list.jsp 继续优化,改成,用js事件来进行下载。

<body>
你好,${message}<br/>
<ul style="list-style: none;">
<c:forEach items="${user.images}" var="imgPath">
<%-- <img src="${pageContext.request.contextPath}${imgPath}" width=100 height=100> <br/> --%>
<li>
<a href="javascript:void(0);" onclick="openDownloadDialog('${pageContext.request.contextPath}${imgPath}')">${imgPath}</a>
</li>
</c:forEach>
</ul>

<script>
function openDownloadDialog(url){
var first = "" , last = "" , name = "" , houZhui = "";
first = url.lastIndexOf("/");//最后一个/的位置
last = url.lastIndexOf(".");//最后一个.的位置
name = url.substr(first+1,last-first-1);//照片名称
houZhui = url.substr(url.lastIndexOf("."));//后缀
var aLink = document.createElement('a');//创建一个虚拟的a标签
aLink.href = url;//这只a标签的url
aLink.download = name + houZhui; // 指定保存文件名,可以不要后缀
var event;
event = document.createEvent('MouseEvents');//创建一个新的MouseEvent对象
event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
aLink.dispatchEvent(event);
}
</script>
</body>

刷新页面,当点击链接之后,会弹出下载对话框,可以进行下载。

SpringMVC的单文件上传,多文件上传和下载文件(十二)_SpringMVC的多文件上传_15

当这上面,只是js的前端下载, 还需要学习后端的下载。

五.三 服务器后端下载

在UserAction 中添加一个download() 下载的方法,传入的是文件的路径 (也可以传入文件的名称),进行操作

@RequestMapping(value="download")
public ResponseEntity<byte[]> download(HttpServletRequest request,
@RequestParam(value="filePath") String fileName) throws UnsupportedEncodingException,
IOException{
//1 获取项目路径
String contextPath=request.getServletContext().getRealPath("/");
System.out.println("输出name:"+fileName);
// 2 拼接下载的文件的路径
File file=new File(contextPath+fileName);
System.out.println("输出文件路径:"+file.toString());
//3 将下载的名称,进行格式转换
String downFileName=new String(fileName.getBytes("utf-8"),"ISO-8859-1");
//4 设置浏览器头部信息,可以下载的设置,设置中文编码,避免出现中文不能下载的情况。
HttpHeaders headers=new HttpHeaders();
headers.setContentDispositionFormData("attachment", downFileName);
//常见的格式,application/oct_stream
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
headers,HttpStatus.CREATED);
}

在前端 重写 list.jsp, a链接的href提交到后端。

<ul style="list-style: none;">
<c:forEach items="${user.images}" var="imgPath">
<li>
<a href="download.action?filePath=${imgPath}">${imgPath}</a>
</li>
</c:forEach>
</ul>

重启服务器,进行验证。

SpringMVC的单文件上传,多文件上传和下载文件(十二)_SpringMVC下载文件_16

谢谢!!!


标签:文件,String,SpringMVC,user,file,message,上传
From: https://blog.51cto.com/u_13420484/5841778

相关文章

  • SpringBoot上传和下载文件(二十七)
    当死亡来临,每一个人都不会接受自己的命运,他们会反抗.上一章简单介绍了SpringBoot启用Https(二十六),如果没有看过,​​请观看上一章​​文件上传和下载,是常用的功能可以看老......
  • 文件操作--设置文件属性、获取文件属性
    1.设置文件属性:SetFileAttributes(文件名,属性值)BOOLWINAPI​​SetFileAttributes​​(_In_ LPCTSTRlpFileName,_In_ DWORD  dwFileAttributes);SetFil......
  • VS各种工程文件说明
    一、sln文件.sln(Solution)解决方案文件,表示一个项目组,他通常包含一个项目中所有的工程文件信息。二、suo文件suo(SolutionUserOptions)解决方案用......
  • cafffe 利用h5py生成多标签h5文件并训练
    h5py生成多标签h5文件importh5pyimportnumpyasnpdefmain():f=h5py.File('train00.h5','w')f.create_dataset('data',(1200,128),dtype='f8')f.create_data......
  • linux 从内存中恢复已删除的文件
    ps-ef|greppython3或者lsof|grep<文件绝对路径>查看打开文件的进程号cd/proc/<进程号>/fd/ll查看当前目录下数字和文件的映射cat<文件对应的数字>><想要恢......
  • 前段使用get获取文件流,实现下载
    functiondownLoad(){    constiframe=document.createElement('iframe')    iframe.style.display='none'    iframe.style.height=......
  • python 解构生成的可执行文件(如main.exe)
    python打包成的main.exe中包含了哪些东西,可以通过以下命令解压到当前目录下一个名为 main.exe_extracted的文件夹中:pythonpyinstxtractor.pymainx.exe文件pyi......
  • PostMan测试文件下载功能
     配置好参数之后点击    这样就会有个弹框弹出来让你选择下载路径了,不同版本可能不一样但是按钮应该差不多 ......
  • Python批量创建文件和文件夹
    Python批量创建文件和文件夹前言:本来计划利用windows批处理脚本批量创建文件和文件夹(文件和文件名称顺序命名),编写批处理脚本过程中,出现很多问题难以解决,耗费时间过多。既......
  • python 代码打包成可执行文件 pyinstaller
    1.打包为一个目录pyinstaller-Dxxx.py2.打包为一个文件pyinstaller-Fxxx.py打包过程中会生成一个xxx.spec文件,如果有自定义的引用,可以修改这个文件,然后执......