其实这样的代码已经烂大街了,客户端代码如下:
let url = UrlService.url('home/upload'),
fileInput = document.getElementById('file-input'),
// 必须创建表单数据
data = new FormData();
// 也可以添加其他数据
data.append('username', 'yiifaa')
// 添加文件内容
data.append('files', fileInput.files[0])
// 提交数据
$.ajax({
url,
data,
// 下面这两项都必须设置为false
contentType: false, // 不设置头部信息
processData: false, // 避免数据处理错误
type: 'POST',
success (datas) {
console.log(datas)
}
})
关于FormData,官方解释是它提供了一种简单构造表单数据的方式,内容组织方式为键值对,提交时组织数据的方式与表单一模一样,唯一不同的是,它的编码方式始终为“multipart/form-data,这也是文件上传必定要采用FormData的原因。
经过上面的设置,数据提交方式将为Payload模式,截图如下:
服务器端代码如下:
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public ActionStatus upload(MultipartHttpServletRequest request) throws IOException {
Iterator<String> itr = request.getFileNames();
String username = request.getParameter("username");
if(itr.hasNext()) {
// 可以取出所有上传的文件
String name = itr.next();
MultipartFile mpf = request.getFile(name);
// 其他处理逻辑,如持久化到数据库或文件系统
}
}
从上面的代码可以看出,Spring MVC可以轻松处理批量文件上传,MVC中的配置信息如下:
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="#{50*1024*1024}"/>
</bean>
但奇怪的是,完全同样的一套代码,部署到WEB容器中完全没有问题,但在Spring Boot中竟然完全无法检测MultipartFile,就跟消失了一模一样,因此你出现了此种情况,建议切换到服务器测试一下。
另外,AJAX提交的数据内容为Payload方式,所以还可以采用@RequestBody进行解析,如下:
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public ActionStatus upload(@RequestBody String body) {
// 用fine-uploader插件进行处理
// github地址为 https://github.com/FineUploader/fine-uploader
}
结论
Spring Boot经常表现出与WEB 容器不一样的形态,再比如Spring Security的表现,所以,微服务虽好,但不一定能轻松解决所有问题。