需求
用springboot配合retrofit上传图片和文字
目录
- 了解http的multipart/form-data
- 学习retrofit上传文件的方法
- 学习springboot接收
multipart/form-data
请求的方法 - 解决方案
- [额外问题] 设置springboot文件传输大小的限制
1. 了解http的multipart/form-data
请先阅读https://www.cnblogs.com/tylerdonet/p/5722858.html。
为了验证,我特意用fiddler模拟了一次文件上传请求。
请求中要上传的信息有:{"auth": "qq", "openId": "...", "accessToken": "...", "wallpaper": "(图片文件)"}。
以下是请求的header和body的截图:
如果想了解Http的其它请求格式,可查看https://blog.csdn.net/qq_33706382/article/details/78168325,其中有form-data
, x-www-form-urlencoded
等。
2. 学习retrofit上传文件的方法
可以先看看Retrofit2 multpart多文件上传详解和Retrofit实现文件上传(二)
接口设置可以分为以下几种:
- 使用
@Multipart
- 使用
@PartMap
@Multipart @POST("UploadServlet") Call<String> uploadFile(@PartMap Map<String, RequestBody> params);
- 使用
@Part
@Multipart @POST("UploadServlet") Call<ResponseBody> upload(@Part("description") RequestBody description, @Part MultipartBody.Part file);
- 使用
- 不使用
@Multipart
, 在参数使用@Body MultipartBody body
我采用的是方法1.1,觉得比较简洁。在后文会晒出我的解决方案。
3. 学习springboot接收multipart/form-data
请求的方法
参考来自https://github.com/ityouknow/spring-boot-examples下的spring-boot-file-upload案例,可以自行git clone
查看代码,并运行查看效果。
4. 解决方案
-
前端:
@Multipart
+@PartMap
public static Map<String, RequestBody> createParams(File wallpaper, String text) { Map<String, RequestBody> params = new HashMap<>(); params.put("wallpaper\"; filename=\"" + "file0.jpg", Util.toRequestBodyOfImage(wallpaper)); params.put("text", Util.toRequestBodyOfText(text)); return params; }
Util.toRequestBodyOfText
和Util.toRequestBodyOfImage
public static RequestBody toRequestBodyOfText (String value) { return RequestBody.create(MediaType.parse("text/plain"), value); } public static RequestBody toRequestBodyOfImage(File file){ return RequestBody.create(MediaType.parse("image/*"), file); }
-
后台:
// Controller内 @PostMapping("/wallpaper") public UploadResponse upload(UploadRequestBody body) { // 参数不要添加@RequestBody }
这里的参数不能是@RequestBody UploadRequestBody body
,否则会报org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;boundary=... not supported
错误
原因: 使用在进行图片或者文件上传时 multipart/form-data 类型时、 数据会自动进行映射不要添加任何注解。(参考https://www.cnblogs.com/yueli/p/7552888.html和https://blog.csdn.net/suxiexingchen/article/details/81214131)
// Bean
public class UploadRequestBody{
private String text;
private MultipartFile wallpaper;
// 根据需要,可以加上private int xx;等属性,但前端也要加上参数传递。
// getter and setters...
}
5. [额外问题] 设置springboot文件传输大小的限制
springboot的文件上传大小默认限制为1MB, 当传输较大的图片时,可能会有以下错误:
org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field wallpaper exceeds its maximum permitted size of 1048576 bytes.
解决方案:
参考https://blog.csdn.net/u013190497/article/details/78731270和
https://blog.csdn.net/kcp606/article/details/78313293。
在application.properties
加上
# 限制改为10MB
multipart.maxFileSize=10240000
multipart.maxRequestSize=10240000
@Configuration
public class FileUploadConfig {
/**
* 文件上传配置
*
* @return MultipartConfigElement
*/
@Bean
public MultipartConfigElement multipartConfigElement(
@Value("${multipart.maxFileSize}") String maxFileSize,
@Value("${multipart.maxRequestSize}") String maxRequestSize) {
MultipartConfigFactory factory = new MultipartConfigFactory();
// 单个文件最大
factory.setMaxFileSize(DataSize.ofBytes(Integer.valueOf(maxFileSize)));
// 设置总上传数据总大小
factory.setMaxRequestSize(DataSize.ofBytes(Integer.valueOf(maxRequestSize)));
return factory.createMultipartConfig();
}
}
要在代码内设置最大文件长度,其中multipart.maxFileSize
和multipart.maxRequestSize
格式应为Integer。