spring mvc--文件上传与错误处理

把用户上传的文件都存放于profiles 文件里

upload-Page.html

<form th:action="@{/upload}" method="post" enctype="multipart/form-data">
	<input type="file" id="file" name="file"/>
	<button type="submit" name="save" th:text="#{submit}">提交</button>
</form>

controller

import org.apache.tomcat.util.htp.fileupload.IOUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springFramework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public static final Resource PICTURES_DIR=new FileSystemResource("./pictures"); //先在pictures目录下创建一个临时文件,java里临时文件只是用于获取文件系统唯一的文件标识符,用户可以自行决定是否要删除
@RequestMapping("upload")
public String uploadPage(){
	return "profile/uploadPage";
}
@RequestMapping(value="/upload",method=RequestMethod.POST)
public String onUpload(MultipartFile file) throws IOException{ //用户提交的数据会以multipartFile接口的形式注入到控制器里,接口提供了一些获取文件名称大小内容的方法
	String filename=file.getOriginalFilename(); //file.getOriginalFilename()是得到上传时的文件名(在IE11/Edge浏览器下面,获取到的路径信息带有盘符)
	File tempFile=File.createTempFile("pic",getFileExtension(filename),PICTURES_DIR.getFile())try(
		InputStream in=file.getInputStream(); //获取输入流之后输出到刚才创建的文件里
		OutputStream out=new FileOutputStream(tempFile)
		){IOUtils.copy(in,out);}
		return "profile/uploadPage";	
}
private static String getFileExtension(String name){
	return name.substring(name.lastTndexOf("."));
}

createNewFile() 方法,根据抽象路径创建一个新的空文件,当抽象路径指定的文件存在时,创建失败,createTempFile(String prefix, String suffix, File directory);
getFileExtension返回文件扩展名
浏览器 采用"multipart/form-data" 的编码方式,可以很容易将表单内的数据和文件放在一起发送
种编码方式先定义好一个不可能在数据中出现的字符串作为 分界符,然后用它将各个数据段分开,而对于每个数据段都对应着 HTML 页面表单 中的一个 Input 区,包括一个 content-disposition 属性,说明了这个数据段的一些信息,如果这个数据段的内容是一个文件,还会有 Content-Type 属性,然后就是数据本身. 我们可以用request.getInputStream()或request.getReader()得到 提交的数据

multipartFile里的getInputStream方法借助了IOUtils.copy方法,可以把流复制到输出流

  • copy能拷贝Integer.MAX_VALUE的字节数据,即2^31-1。
  • 如果是很大的数据,那么可以选择用copyLarge方法,适合拷贝较大的数据流,比如2G以上
    上传的文件不是以静态目录的方式使用的,所以需要采取一些操作在web页面展示,比如图片
    在html里加入展示图片区
<img th:src="@{/uploadedFile}" width="100" height="100"/>

controller里添加获取文件的方法

@RequestMapping(value="/uploadedFile")
public void getUploadedFile(HttpServletResponse response) throws IOException{
	ClassPathResource classPathResource=new ClassPathResource("/images/anonymous.png");
	response.setHeader("Content-Type",URLConnection.guessContentTypeFormName(classPathResource.getFilename()));
	IOUtils.copy(classPathResource.getInputStream(),response.getOutputStream());
}

这段代码把src/main/resources/images/anonymous.png图片写到响应里

管理上传属性

最好通过application.properties文件配置上传目录以及匿名用户图片的路径
1.在新创建的config包里定义一个pictureUploadProperties类

@ConfigurationProperties(prefix="upload.pictures") //告诉springboot以一种类型安全的方式自动映射类路径下所发现的属性(一般是位于application.properties文件里)
public class PictureUploadProperties{
	private Resource uploadPath;
	private Resource anonymousPicture;
	public Resource getAnonymousPicture(){
	return anonymousPicture;
	}
	public void setAnonymousPicture(String anonymousPicture){
		this.anonymousPicture=new DefaultResourceLoader().getResource(anonymousPicture);
	}
	public Resource getUploadPath(){
		return uploadPath;
	}
	public void setUploadPath(String uploadPath){
		this.uploadPath=new DefaultResourceLoader().getResource(uploadPath);
	}
}

之后把pictureUploadProperties添加到配置里

@SpringBootApplication
@EnableConfigurationProperties({PictureUploadProperties.class})
public class MasterSpringMvc4Applicationextends webMvcConfiguerAdapter{//code}

然后在application.properties文件里添加如下属性值

upload.pictures.uploadPath=file:./picturesupload.pictures.anonymousPicture=classpath:/images/anonymous.png

因为使用的是defaultResourceLoader类,所以可以使用像file:或classpath:这样的前缀来指定查找资源的位置,等价于分别创建fileSystemResource和ClassPathResource类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值