1、实际需求
图片的上传接口,在平时的使用中,大多数的情况下,都是使用纯上传图片的接口;但是在某些情况下,需要接口支持文本信息及图片同时上传;
比如: 需要记录用户的行为数据记录时,可能需要记录用户的行为数据,又需要支持上传用户行为的图片;虽然使用2个接口也能完成需求的设计,但是将行为记录的接口分开成2个,就需要特别处理失败时的事务管理,然而在分布式的环境下,事务的管理变得更加复杂,等于是将简单的需求复杂化,得不偿失。
2、接口支持单张图片上传
@Api(tags = "图片文件上传API")
@RestController("/image/upload")
public class UploadController {
private static final String UPLOAD_PATH = "E:\\workCode\\opencv-demo\\src\\main\\resources\\upload";
@ApiOperation("上传头像图片文件")
@PostMapping("/avatar")
public String uploadAvatar(@RequestParam(value = "file", required = true) MultipartFile file) throws IOException {
String fileName = System.currentTimeMillis() + file.getOriginalFilename();
File destFile = new File(UPLOAD_PATH + "\\" + fileName);
// 创建目标文件的存储路径
destFile.getParentFile().mkdirs();
// 上传的图片文件转化为目标文件
file.transferTo(destFile);
return "success upload : " + fileName;
}
}
swagger测试结果:
3、接口支持多张图片上传的设计
4、支持文本信息及多张图片同时上传的设计
@Api(tags = "图片文件上传API")
@RestController("/image/upload")
public class UploadController {
private static final String UPLOAD_BASE_PATH = "E:\\workCode\\opencv-demo\\src\\main\\resources";
@ApiOperation("上传多张头像图片文件及上传的文件路径")
@PostMapping("/avatar/all")
public String uploadAvatarAndFilePath(@RequestPart(value = "uploadInfoDTO") UploadInfoDTO uploadInfoDTO,
@RequestPart(value = "files", required = true) MultipartFile[] files) throws IOException {
if (files.length < 0) {
return "upload fail.";
}
for (int i = 0; i < files.length; i++) {
String fileName = uploadInfoDTO.getUserName() + "\\" + uploadInfoDTO.getImageType()
+ System.currentTimeMillis() + files[i].getOriginalFilename();
File destFile = new File(UPLOAD_BASE_PATH + "\\" + fileName);
// 创建目标文件的存储路径
destFile.getParentFile().mkdirs();
// 上传的图片文件转化为目标文件
files[i].transferTo(destFile);
}
return "success upload : " + files.length;
}
}
swagger测试结果:
swagger文档不知道怎么配置图片文件和文本的格式,没办法进行调用区分,导致请求报错,需要用postMan来进行请求调用
psotMan的测试参数设置:
文本信息的类型设置为:application/json,图片文件参数files指定为文件上传类型
postMan测试结果:
5、总结
在测试同时上传图片文件和文本信息的接口时,习惯性使用swagger提供的接口测试界面,进行接口测试,发现调用接口失败,一度怀疑自己是不是写错了接口;
{
"timestamp": "2021-09-17T02:01:58.027+00:00",
"status": 415,
"error": "Unsupported Media Type",
"message": "",
"path": "/avatar/all"
}
上面的报错信息,差点让我放弃这个接口,将接口拆分成2个,后面重新思考了一下,觉得可能是接口请求没有告诉后端,按照特定的格式去解析接口的请求参数,导致出现的解析错误;请求参数中的图片文件属于字节流,而文本信息中的参数则数据字符流,若不把二种不同流的解析方式告诉后端接口,后端接口直接以默认的一个流格式去解析参数,就会出现解析参数出错。
想到问题出现的原因后,决定改用postMan来进行接口测试,然后给files参数指定为文件类型,将文本参数uploadInfoDTO指定ContentType为:application/json,之后调用后端接口,请求调用正常通过。
其实更底层的原因是HTTP请求协议没有彻底理解,没有搞懂请求的文本信息和文件信息的流解析流程,后续有机会再深入研究下HTTP的协议设计。
源码链接:opencv: learn opencv on javahttps://gitee.com/wqzhuang/opencv