目录
1、单文件上传
2、多文件上传
3、下载、在线查看
4、上传文件大小限制
5、自定义上传文件超过限制异常
这里的enctype的类型是mulitpart/form-data
两种形式的提交,一种是以form表单的形式,一个是ajax的形式
上传文件
我们将上传的文件放入到resources下面
这里不能使用request.getServletContext().getRealPath(""),因为这里获取到的路径是tomcat临时文件的目录
springboot中request.getServletContext().getRealPath(“/”)获取的是一个临时文件夹的地址_猿程序plus的博客-CSDN博客_springboot 获取临时目录
@PostMapping("upload")
@ResponseBody
//将上传的文件放在tomcat目录下面的file文件夹中
public String upload(MultipartFile multipartFile, HttpServletRequest request, HttpServletResponse response) throws IOException {
//获取到原文件全名
String originalFilename = multipartFile.getOriginalFilename();
// request.getServletContext()。getRealPath("")这里不能使用这个,这个是获取servlet的对象,并获取到的一个临时文件的路径,所以这里不能使用这个
//这里获取到我们项目的根目录,classpath下面
String realPath = ResourceUtils.getURL(ResourceUtils.CLASSPATH_URL_PREFIX).getPath();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String format = simpleDateFormat.format(new Date());
//文件夹路径,这里以时间作为目录
String path = realPath + "static/" + format;
//判断文件夹是否存在,存在就不需要重新创建,不存在就创建
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
//转换成对应的文件存储,new File第一个参数是目录的路径,第二个参数是文件的完整名字
multipartFile.transferTo(new File(file, originalFilename));
//上传文件的全路径
String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/" + format + "/" + originalFilename;
return url;
}
多文件上传需要有multiple属性,我们也可以使用accept来利用前端来进行上传文件的指定
上传文件
多文件的上传跟单文件其实差不多,就是对多文件遍历
@PostMapping("upload1")
@ResponseBody
//将上传的文件放在tomcat目录下面的file文件夹中
public String upload1(MultipartFile[] files, HttpServletRequest request, HttpServletResponse response) throws IOException {
List list = new ArrayList<>();
//System.out.println(files.length);
for (MultipartFile multipartFile : files) {
//获取到文件全名
String originalFilename = multipartFile.getOriginalFilename();
// request.getServletContext()。getRealPath("")这里不能使用这个,这个是获取servlet的对象,并获取到的一个临时文件的路径,所以这里不能使用这个
//这里获取到我们项目的根目录,classpath下面
String realPath = ResourceUtils.getURL(ResourceUtils.CLASSPATH_URL_PREFIX).getPath();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String format = simpleDateFormat.format(new Date());
//文件夹路径,这里以时间作为目录
String path = realPath + "static/" + format;
//判断文件夹是否存在,存在就不需要重新创建,不存在就创建
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
//转换成对应的文件存储,new File第一个参数是目录的路径,第二个参数是文件的完整名字
multipartFile.transferTo(new File(file, originalFilename));
//上传文件的全路径,一般是放在tomcat中
String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/" + format + "/" + originalFilename;
//System.out.println("url=》》》》》"+url);
list.add(url);
}
return new ObjectMapper().writeValueAsString(list);
}
进行文件下载的时候注意我们最好不要创建一个文件大小的数组来直接读取我们的文件,在文件过大的情况下,可能会导致内存溢出,可以根据实际情况,调整一次读取文件的大小,多次进行读取并输出
@RequestMapping("download")
public void download(HttpServletRequest request, HttpServletResponse response, String name, @RequestParam(defaultValue = "0") int isOnline) throws IOException {
try (ServletOutputStream outputStream = response.getOutputStream();) {
/*
这里要使用ResourceUtils来获取到我们项目的根目录
不能使用request.getServletContext().getRealPath("/"),这里获取的是临时文件的根目录(所以不能使用这个)
*/
String path = ResourceUtils.getURL(ResourceUtils.CLASSPATH_URL_PREFIX).getPath();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String format = simpleDateFormat.format(new Date());
String realPath = path + "static/" + format + "/" + name;
File file = new File(realPath);
//如果下载的文件不存在
if (!file.exists()) {
response.setContentType("text/html;charset=utf-8");
//response.getWriter().write(str);这种写入的就相当于生成了jsp/html,返回html/jsp,所以需要我们进行contentType的设置
response.getWriter().write("下载的文件不存在");
return;
}
InputStream in = new FileInputStream(realPath);
int read;
//byte[] b = new byte[in.available()];创建一个输入流大小的字节数组,然后把输入流中所有的数据都写入到数组中
byte[] b = new byte[1024];
/*
1、Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存
2、attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"
3、filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
*/
/* 注意:文件名字如果是中文会出现乱码:解决办法:
1、将name 替换为 new String(filename.getBytes(), "ISO8859-1");
2、将name 替换为 URLEncoder.encode(filename, "utf-8");
*/
if (isOnline == 0) {
//在线打开
response.addHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(name, "utf-8"));
} else {
//下载形式,一般跟application/octet-stream一起使用
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(name, "utf-8"));
//如果单纯写这个也可以进行下载功能,表示以二进制流的形式
response.setContentType("application/octet-stream");
}
//文件大小
response.addHeader("Content-Length", "" + file.length());
while ((read = in.read(b)) > 0) {
outputStream.write(b);
}
} catch (Exception e) {
System.out.println(e.getMessage());
throw e;
}
}
默认的单文件大小是1m,多文件的总大小10m,超过就会报MaxUploadSizeExceededException异常
我们根据实际情况进行调整
例如
springboot自带的异常显示很多时候都不是我们自己想要的,那么对于这种异常,我们可以使用自定义异常来进行显示
package org.springframework.myspringboot.exception;
import org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.Max;
import java.io.IOException;
/**
* @author winnie
* @PackageName:org.springframework.myspringboot.exception
* @Description TODO
* @date 2022/8/3 18:25
*/
@ControllerAdvice
public class MyCustomMaxUploadSizeException {
//这里注意如果是参数中有不存在的参数就会导致我们的全局异常失效
@ExceptionHandler(value = MaxUploadSizeExceededException.class)
@ResponseBody
public String MyException(HttpServletRequest request,
HttpServletResponse response,
MaxUploadSizeExceededException e
)throws IOException {
// response.setContentType("text/html;charset=utf-8");
// response.getWriter().write("上传的文件的大小是超过了最大限制");
return "上传的文件的大小是超过了最大限制";
}
}
这里是一个比较简单的demo,我们也可以返回自定义的错误视图
例如,引入thymeleaf依赖
org.springframework.boot
spring-boot-starter-thymeleaf
2.2.5.snapshot
package org.springframework.myspringboot.exception;
import org.springframework.boot.logging.java.SimpleFormatter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.View;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author winnie
* @PackageName:org.springframework.myspringboot.exception
* @Description TODO
* @date 2022/8/3 18:25
*/
@ControllerAdvice
public class MyCustomMaxUploadSizeException {
//这里注意如果是参数中有不存在的参数就会导致我们的全局异常失效
@ExceptionHandler(value = MaxUploadSizeExceededException.class)
public ModelAndView MyException(HttpServletRequest request,
HttpServletResponse response,
MaxUploadSizeExceededException e
)throws IOException {
// response.setContentType("text/html;charset=utf-8");
// response.getWriter().write("上传的文件的大小是超过了最大限制");
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("error",e.getMessage());
modelAndView.addObject("date",new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
modelAndView.setViewName("uploadException.html");
return modelAndView;
}
}
上传文件大小超过限制
上传文件超过大小
发生异常的日期:
异常信息:
发生异常的时候