Servlet3.0提供了对文件上传的原生支持,不需借助任何第三方组件,直接使用Servlet3.0提供的API就能够实现文件上传功能。本文使用IDEA IDE工具,在Spring MVC框架下,基于注解映射和数据绑定编写Java业务代码,利用Servlet3.0 API来实现单个文件的上传示例。
部署配置文件
MultipartConfig Servlet
在部署描述符中的DispatcherServlet中声明赋值,使其Servlet变成MultipartConfig Servlet,具体添加以下标签内容:
<servlet
>
<servlet
-name>springmvc
</servlet
-name>
<servlet
-class>org
.springframework
.web
.servlet
.DispatcherServlet
</servlet
-class>
<init
-param>
<param
-name>contextConfigLocation
</param
-name>
<param
-value>/WEB
-INF/springmvc
-servlet.xml</param
-value>
</init
-param>
<load
-on-startup>2</load
-on-startup>
<multipart
-config>
<max-file-size>1000000</
max-file-size>
</multipart
-config>
</servlet
>
<servlet
-mapping>
<servlet
-name>springmvc
</servlet
-name>
<url
-pattern>/</url
-pattern>
</servlet
-mapping>
添加原因:Spring MVC无法直接对Servlet进行注解。另一种方法是用@MultipartConfig给DispatcherServlet进行注解,效果一样。
MultipartResolver
在Spring MVC配置文件中添加一个不同的多部分解析器,具体添加以下内容:
<bean id=
"multipartResolver" class=
"org.springframework.web.multipart.support.StandardServletMultipartResolver">
</bean>
编写Java代码
Domain类
/**
* UploadFile.java
*
* @author Zero
*/
public class UploadFile implements Serializable {
private static final long serialVersionUID =
123456789L;
private MultipartFile multipartFile;
private String description;
public static long getSerialVersionUID() {
return serialVersionUID;
}
public MultipartFile
getMultipartFile() {
return multipartFile;
}
public void setMultipartFile(MultipartFile multipartFile) {
this.multipartFile = multipartFile;
}
public String
getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
Service接口与实现类
/**
* MyFileService.java
*
* @author Zero
*/
public interface MyFileService {
String uploadFile(UploadFile uploadFile, String realPath);
}
@Service(
"myFileService")
public class MyFileServiceImpl implements MyFileService {
private static final String UPLOAD_ERROR =
"文件上传出错!";
private static final String UPLOAD_SUCCESS =
"文件上传成功!";
@Override
public String
uploadFile(UploadFile uploadFile, String realPath) {
boolean loadFileVerify =
false;
MultipartFile multipartFile = uploadFile.getMultipartFile();
String fileName = multipartFile.getOriginalFilename();
File file =
new File(realPath, fileName);
try {
multipartFile.transferTo(file);
loadFileVerify =
true;
}
catch (IOException e) {
e.printStackTrace();
}
return loadFileVerify ? UPLOAD_SUCCESS : UPLOAD_ERROR;
}
}
Controller类
/**
* MyFileController.java
*
* @author Zero
*/
@Controller
@RequestMapping(
"/public/")
public class MyFileController {
private static Logger LOG = LoggerFactory.getLogger(FileController.class);
private static final String UPLOAD_EMPTY =
"文件为空!";
@Autowired
private MyFileService fileService;
@RequestMapping(value =
"file_upload", method = RequestMethod.POST)
public String
upload(@
ModelAttribute(uploadFile) @Valid UploadFile uploadFile, BindingResult result, HttpServletRequest request, Model model) {
if (result.hasErrors()) {
LOG.warn(UPLOAD_EMPTY);
model.addAttribute(
"uploadResult", UPLOAD_EMPTY);
return "index";
}
String uploadResult = fileService.uploadFile(uploadFile, request.getServletContext().getRealPath(
"/file"));
model.addAttribute(
"uploadResult", uploadResult);
return "index";
}
}
编写前端页面代码
编写JSP测试表单
//index.jsp
<form action="public/file_upload" method="post" enctype="multipart/form-data">
<h4>File Upload
</h4>
<div class="form-group">
<label for="multipartFile">File select:
</label>
<input type="file" name="multipartFile" id="multipartFile"/>
</div>
<div class="form-group">
<label for="description">File description:
</label>
<input type="text" name="description" id="description"/>
</div>
<div class="form-group">
<input type="submit" value="upload"/>
<p >${uploadResult}
</p>
</div>
</form>
注意事项
1.若BindingResult返回false,可能是domain类参数匹配不对,特别是serialVersionUID,需用idea自生成; 2.若表单post提交的multipartFile数据无法绑定到后台对应属性,可能是表单配置不对enctype=”multipart/form-data”。