1 单文件上传
在程序开发中,有时候需要上传一些文件。我们在学习Servlet的时候,也做过文件上传的操作,只不过基于Servlet的文件上传操作起来过于复杂,因此所有的MVC框架都提供了自己的文件上传操作,基本上都是基于FileUpload的文件上传。
Spring MVC在处理文件上传的时候,有自己的处理方法,但是也是基于FileUpload的操作,因此在处理文件上传的时候也需要导入commons-fileupload-1.2.2.jar包和commons-io-2.4.jar包。
在操作的时候,首先需要在配置文件中,配置Spring MVC文件上传功能,具体代码如下。
<!-- 设置了multipartResolver才能完成文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 文件上传字符编码 -->
<property name="defaultEncoding" value="UTF-8"></property>
<!-- 设置文件上传的大小,单位是字节 -->
<property name="maxUploadSize" value="2000000"></property>
</bean>
接下来需要一个表单,用来执行选择文件操作,首先在控制器中添加方法,用来跳转到文件上传页面,具体代码如下。
@RequestMapping(value="/uploadInput", method=RequestMethod.GET)
public String upload() {
return "upload";
}
在WEB-INF/jsp目录下创建upload.jsp页面,并添加如下代码。
<form action="upload" method="post" enctype="multipart/form-data">
name:<input type="text" name="name"><br>
file:<input type="file" name="fileName"><br>
<input type="submit" value="提交">
</form>
页面效果如图所示。
在控制器中只需要在处理方法中加入参数MultipartFile,就可以实现文件上传了。编写处理方法,代码内容如下。
@RequestMapping(value="/upload", method=RequestMethod.POST)
public String upload(String name, MultipartFile file, HttpServletRequest req) {
System.out.println(name);
//获取表单域的名字
System.out.println(file.getName());
//获取文件原始的名字
System.out.println(file.getOriginalFilename());
//获取文件的类型
System.out.println(file.getContentType());
//获取文件上传的路径
String realpath = req.getSession().getServletContext().getRealPath("/upload");
//创建文件对象
File f = new File(realpath + "/" + file.getOriginalFilename());
try {
//文件上传
FileUtils.copyInputStreamToFile(file.getInputStream(), f);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "upload";
}
注意:方法中MultipartFile对象的名字,必须和文件表单域的名字一致,否则会报错。
在WebRoot目录下创建文件夹upload,访问:http://localhost:8080/springmvc/uploadInput,选择文件,就可以正常上传文件了。
2 多文件上传
在实际的开发中,有时要同时上传多个文件,在处理的时候,只需要稍作修改就可以了。首先需要修改文件上传页面代码,如下所示。
<form action="upload" method="post" enctype="multipart/form-data">
name:<input type="text" name="name" size="30"><br><br>
file:<input type="file" name="files"><br><br>
file:<input type="file" name="files"><br><br>
file:<input type="file" name="files"><br><br>
<input type="submit" value="提交">
</form>
页面显示的效果如图所示。
在控制器中的处理也非常简单,只需要把对象改为一个数组即可,代码修改如下。
@RequestMapping(value="/upload", method=RequestMethod.POST)
public String upload(String name, MultipartFile files[], HttpServletRequest req) {
//获取文件上传的路径
String realpath = req.getSession().getServletContext().getRealPath("/upload");
for(MultipartFile file:files) {
//在多文件上传时,防止有的文件表单域没有选择文件
if(file.isEmpty()) {
continue;
}
//创建文件对象
File f = new File(realpath + "/" + file.getOriginalFilename());
try {
//文件上传 FileUtils.copyInputStreamToFile(file.getInputStream(), f);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return "success";
}
此时选择多个文件,也能同时完成上传,即使有的表单域没有选择文件,也是可以的,同时这种方法同样也能完成单文件的上传。不过这样做也有点费事,在实际开发中往往都是通过插件,使在一个选择框中,可以同时选择若干文件,实现同时上传。这一点在HTML5中,可以通过multiple属性来实现在一个文件表单域中可接受多个值的文件上传,在HTML4中仍然可以使用,具体代码如下所示。
<form action="upload" method="post" enctype="multipart/form-data">
name:<input type="text" name="name" size="30"><br><br>
file:<input type="file" name="files" multiple="multiple"><br><br>
<input type="submit" value="提交">
</form>
页面效果如图所示。
后台接收文件的处理代码不用修改,可以直接使用。