【Java Web开发学习】Spring MVC文件上传
文件上传有两种实现方式,都比较简单
方式一、使用StandardServletMultipartResolver
依赖Servlet3.0对Multipart请求的支持,需要MultipartConfigElement配置请求的相关参数
Java配置方式
@BeanpublicMultipartResolver multipartResolver() {return newStandardServletMultipartResolver();
}
在Servlet中指定multipart配置,通过MultipartConfigElement设置上传临时路径,上传文件大小,上传请求的大小。
通过重载protected void customizeRegistration(ServletRegistration.Dynamic registration)方法实现,看代码
packagecn.ycx.web.config;importjava.io.IOException;importjava.util.Properties;importjavax.servlet.MultipartConfigElement;importjavax.servlet.ServletRegistration;importorg.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;public class ServletInitializer extendsAbstractAnnotationConfigDispatcherServletInitializer {//将一个或多个路径映射到DispatcherServlet上
@OverrideprotectedString[] getServletMappings() {return new String[] {"/"};
}//返回的带有@Configuration注解的类将会用来配置ContextLoaderListener创建的应用上下文中的bean
@Overrideprotected Class>[] getRootConfigClasses() {return new Class>[] {RootConfig.class};
}
@Overrideprotected Class>[] getServletConfigClasses() {return new Class>[] {ServletConfig.class};
}
@Overrideprotected void customizeRegistration(ServletRegistration.Dynamic registration) {
// 上传文件的临时目录
String location = "/tmp";
// 上传文件的最大容量
long maxFileSize = 3145728;
// 请求的最大容量
long maxRequestSize = 3145728;
// 上传的最小临界值,大于该值才会被写入文件保存
// int fileSizeThreshold = 0;
try {
Properties prop = new Properties();
prop.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("upload.properties"));
location = prop.getProperty("temporary.location");
maxFileSize = Long.parseLong(prop.getProperty("max.file.size"));
maxRequestSize = Long.parseLong(prop.getProperty("max.request.size"));
} catch (IOException e) {}
// 文件上传配置
registration.setMultipartConfig(new MultipartConfigElement(location, maxFileSize, maxRequestSize, 0));
// 没有找到处理的请求抛出异常
boolean done = registration.setInitParameter("throwExceptionIfNoHandlerFound", "true");
if(!done) throw new RuntimeException("设置异常(throwExceptionIfNoHandlerFound)");
}
}
xml-base方式
web.xml配置DispatcherServlet初始化参数
...省略...
dispatcher
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:dispatcher-servlet.xml
0
E:/tmp
3145728
3145728
...省略...
Html代码
Insert title here1、控制器接受文件原始byte[]。这种方式不可取,虽然能保存文件,但是我们不知道文件原始名称,也不知道文件类型。
@RequestMapping("/upload")public Map upload(@RequestPart("fileData") byte[] fileData) throwsException {
SimpleDateFormat format= new SimpleDateFormat("yyyyMMddHHssmm");if (fileData != null) {
FileOutputStream out= new FileOutputStream(new File("F:\\war\\" + format.format(newDate())));
out.write(fileData);
out.close();
}
Map data = new HashMap();
data.put("status", "ok");returndata;
}
2、控制器接受MultipartFile类型
Multipart接口
public interface MultipartFile extendsInputStreamSource {
String getName();//参数名字
String getOriginalFilename();//原始文件名
String getContentType();//类型
boolean isEmpty();//文件是否空
long getSize();//文件字节大小
byte[] getBytes() throws IOException;//返回字节数组
@Override
InputStream getInputStream()throws IOException;//输入流
void transferTo(File dest) throws IOException, IllegalStateException;//转换文件
}
控制器代码
@RequestMapping("/upload")public Map upload(MultipartFile fileData) throwsException {if (fileData != null) {
SimpleDateFormat format= new SimpleDateFormat("yyyyMMddHHssmm");
fileData.transferTo(new File("F:\\war\\" + format.format(new Date()) + "_" +fileData.getOriginalFilename()));//保存文件
}
Map data = new HashMap();
data.put("status", "ok");returndata;
}
3、控制器接受Part类型
Part接口
public interfacePart {public InputStream getInputStream() throws IOException;//输入流
public String getContentType();//类型
public String getName();//参数名
public String getSubmittedFileName();//原始文件名
public long getSize();//字节大小
public void write(String fileName) throws IOException;//保存文件
public void delete() throws IOException;//删除文件
public String getHeader(String name);//获取头信息
public Collection getHeaders(String name);//获取头信息
public Collection getHeaderNames();//获取头信息
}
控制器代码
@RequestMapping("/upload")public Map upload(@RequestPart("fileData") Part fileData) throwsException {if (fileData != null) {
SimpleDateFormat format= new SimpleDateFormat("yyyyMMddHHssmm");
fileData.write("F:\\war\\" + format.format(new Date()) + "_" +fileData.getSubmittedFileName());//保存文件
}
Map data = new HashMap();
data.put("status", "ok");returndata;
}
方式二、使用CommonsMultipartResolver
依赖 commons-fileupload.jar 和 commons-io.jar。上传临时路径,文件大小都在对象中设置。
code-base方式
@Beanpublic MultipartResolver multipartResolver() throwsIOException {
CommonsMultipartResolver multipartResolver= newCommonsMultipartResolver();
multipartResolver.setUploadTempDir(newFileSystemResource(config.uploadTemporaryLocation()));
multipartResolver.setMaxUploadSize(config.uploadMaxFileSize());
multipartResolver.setMaxInMemorySize(0);returnmultipartResolver;
}
xml-base方式
示例代码:
实现了核心部分仅供参考。
packagecn.ycx.web.controller;importjava.io.File;importjava.io.IOException;importjava.text.SimpleDateFormat;importjava.util.Date;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestMethod;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.ResponseBody;importorg.springframework.web.multipart.MultipartFile;importcn.ycx.web.config.PropertyConfig;/*** 上传
*@author杨崇兴 2018-07-09*/@Controller
@RequestMapping("/upload")public class UploadController extendsBaseController {/*** 属性配置*/@AutowiredprivatePropertyConfig config;
@RequestMapping(value="/image", method=RequestMethod.POST, produces="application/json;charset=UTF-8")public String image(@RequestParam(value = "imageFile", required = false) MultipartFile multipartFile) {try{
String serverPath= config.uploadImageSavePath() + new SimpleDateFormat("yyyy/MM/dd/").format(newDate());
File serverPathFile= newFile(serverPath);//目录不存在则创建
if (!serverPathFile.exists()) {
serverPathFile.mkdirs();
}
String fileName=multipartFile.getOriginalFilename();
multipartFile.transferTo(new File(serverPath +fileName));
}catch(IllegalStateException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}return "success";
}
}
上传