文章目录
multipart格式数据会将一个表单拆分为多个部分,每个部分对应一个输入域
配置multipart解析器
Spring内置multipart解析器
- CommonsMultipartResolver:使用Jakarta Commons FileUpload解析multipart请求;
- StandardServletMultipartResolver:依赖于Servlet3.0对multipart请求的支持。
StandardServletMultipartResolver
@Bean
public MultipartResolver multipartResolver() throw IOException{
return new StandardServletMultipartResolver();
}
上述代码完成了对StandardServletMultipartResolver
的配置。
在Servlet中指定multipart的配置,来配置限制条件。我们必须在web.xml或Servlet初始化类中,将multipart的具体细节作为DispatcherServlet配置的一部分,如下所示:
public class MyServletInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
DispatcherServlet ds = new DispatcherServlet();
ServletRegistration.Dynamic registration = servletContext.addServlet("appServlet", ds);
registration.addMapping("/");
registration.setMultipartConfig(new MultipartConfigElement("/tmp/"));
}
}
对于继承了AbstractAnnotationConfigDispatcherServletInitializer或AbstractDispatcher-ServletInitializer
的servlet初始化类,不需创建并注册DispatcherServlet,通过重载customizeRegistration(Dynamic registration)方法即可设置上述限制条件
MultipartConfigElement构造器,其所能接受的参数有:
- maxFileSize:上传文件的最大容量(字节为单位),默认无限制;
- maxRequestSize:multipart请求最大容量(字节为单位),默认无限制
- fileSizeThreshold:指定最大容量(字节为单位),达到后文件写入临时文件路径,默认为0,即所有文件都会写入磁盘
eg:限制文件大小不超过2M,整个请求不超过4M,所有文件都要写到磁盘中。
@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration){
//设置MultipartConfigElement
registration.setMultipartConfig(
//设置上传文件的临时存储目录
new MultipartConfigElement("/tmp/spittr/uploads", 2097152, 4094304, 0)
);
CommonsMultipartResolver
一般不用,在Servlet版本较低时可用于替代上面resolver
@Bean
public MultipartResolver multipartResolver() throws IOException {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(2097152);
multipartResolver.setUploadTempDir(new FileSystemResource("/tmp/spittr/uploads"));
multipartResolver.setMaxInMemorySize(0);
return multipartResolver;
}
处理multipart请求
原始byte[]形式
@PostMapping("/file")
public String uploadFile(@RequestPart("profileFile") byte[] profileFile,
@Valid FileMode fileMode,
Errors errors) throws IOException {
BufferedOutputStream bos = null;
FileOutputStream fos = null;
String path = "/Users/xmly/Desktop/";
try {
File dir = new File(path);
if(!dir.exists() && dir.isDirectory()){
dir.mkdirs();
}
File file = new File(path + fileMode.getName());
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(profileFile);
} catch (IOException e) {
e.printStackTrace();
} finally {
if(bos != null){
try{
bos.close();
}catch (IOException e1){
e1.printStackTrace();
}
}
if(fos != null){
try{
fos.close();
}catch(IOException e2) {
e2.printStackTrace();
}
}
}
return "success";
}
上述代码中,@RequestPart()
注解指定的参数包含了请求中对应part的数据(文件内容),形式为byte[]。
MultipartFile形式
处理multipart数据的高级方式,为处理提供更丰富的对象。
@PostMapping("/file/multipart")
public String uploadFile(@RequestParam("profileFile") MultipartFile profileFile,
HttpServletRequest request) throws IOException {
BufferedOutputStream bos = null;
FileOutputStream fos = null;
try {
//获取文件类型
String type = profileFile.getContentType();
//获取参数名
String name = profileFile.getName();
//获取文件名
String originalName = profileFile.getOriginalFilename();
String path = "/Users/xmly/Desktop/";
File file = new File(path + originalName);
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
//获取文件内容
bos.write(profileFile.getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
if(bos != null){
try{
bos.close();
}catch (IOException e1){
e1.printStackTrace();
}
}
if(fos != null){
try{
fos.close();
}catch(IOException e2) {
e2.printStackTrace();
}
}
}
return "success";
}
上述代码为使用MultipartFile类型数据接收上传文件数据的方式,还可以直接从request中获取,代码如下:
@PostMapping("/file/multipart/request")
public String uploadFile3(HttpServletRequest request) throws IOException {
StandardServletMultipartResolver resolver = new StandardServletMultipartResolver();
//判断是否为multipart请求
if(resolver.isMultipart(request)){
MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest)request;
List<MultipartFile> list = multipartHttpServletRequest.getFiles("profileFile");
list.forEach(file -> {
BufferedOutputStream bos = null;
FileOutputStream fos = null;
try {
//获取文件类型
String type = file.getContentType();
String name = file.getName();
String originalName = file.getOriginalFilename();
String path = "/Users/xmly/Desktop/";
File file1 = new File(path + originalName);
fos = new FileOutputStream(file1);
bos = new BufferedOutputStream(fos);
bos.write(file.getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
if(bos != null){
try{
bos.close();
}catch (IOException e1){
e1.printStackTrace();
}
}
if(fos != null){
try{
fos.close();
}catch(IOException e2) {
e2.printStackTrace();
}
}
}
});
}
return "success";
}
以part形式接收上传的文件
@PostMapping("/file/multipart")
public String uploadFile2(@RequestParam("profileFile") Part profileFile){
...
}
Part
与MultipartFile接口差别不大;编写控制器时,若用Part来接受文件上传,则无需配置MultipartResolver。
其中包含的方法如下: