Spring Boot @RestController上传报错:Android Retrofit/OkHttp3传图遇415错误
415 Unsupported Media Type 问题解决指南
嘿,刚接触Spring Boot和Android开发就碰到文件上传的问题很正常,咱们先把这个报错拆解清楚:
{"timestamp":1519756785858,"status":415,"error":"Unsupported Media Type","exception":"org.springframework.web.HttpMediaTypeNotSupportedException","message":"Content type 'text/plain;charset=utf-8' not supported","path":"/uploadImage"}
这个报错的核心意思是:你的Android客户端发送请求时,把Content-Type设成了text/plain(纯文本格式),但Spring Boot服务器端只接受用于文件上传的multipart/form-data格式,所以直接拒绝了请求。
下面分两端给你具体的修正方案:
一、Android端(Retrofit + OkHttp3)要这么改
关键是让请求正确使用multipart/form-data格式,这得靠Retrofit的@Multipart注解来实现:
1. 定义正确的Retrofit接口
public interface UploadApi { // 必须加@Multipart注解,它会自动设置Content-Type为multipart/form-data @Multipart @POST("/uploadImage") Call<ResponseBody> uploadImage( // 用MultipartBody.Part包装图片文件 @Part MultipartBody.Part imageFile, // 可选:如果需要传额外的文本参数,用@Part包装RequestBody @Part("remark") RequestBody remark ); }
2. 构建请求体并发起上传
// 1. 准备要上传的图片文件(这里示例是从本地路径取,你可以换成相册/相机的文件路径) File picFile = new File(Environment.getExternalStorageDirectory() + "/test_photo.jpg"); // 2. 为图片创建RequestBody,指定媒体类型为image/jpeg(如果是PNG就用image/png) RequestBody picRequestBody = RequestBody.create(MediaType.parse("image/jpeg"), picFile); // 3. 把图片包装成MultipartBody.Part,注意第一个参数"file"要和服务器端接收的参数名一致! MultipartBody.Part picPart = MultipartBody.Part.createFormData("file", picFile.getName(), picRequestBody); // 可选:如果要传文本参数,也用RequestBody包装 RequestBody remark = RequestBody.create(MediaType.parse("text/plain"), "这是一张测试图片"); // 4. 创建Retrofit实例并发起请求 Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://你的服务器IP:端口号") // 替换成你的服务器地址 .client(new OkHttpClient()) .build(); UploadApi uploadApi = retrofit.create(UploadApi.class); Call<ResponseBody> call = uploadApi.uploadImage(picPart, remark); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { // 处理上传成功的逻辑 if (response.isSuccessful()) { // 比如弹出Toast提示上传成功 } } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { // 处理上传失败的逻辑,比如打印错误日志 t.printStackTrace(); } });
二、Spring Boot端的配置要跟上
确保你的服务器接口能正确接收multipart/form-data类型的文件:
1. 编写上传接口
@RestController public class UploadController { @PostMapping("/uploadImage") public ResponseEntity<String> handleImageUpload( // @RequestParam的"file"必须和Android端createFormData的第一个参数完全一致! @RequestParam("file") MultipartFile imageFile, // 可选:接收Android端传的文本参数 @RequestParam(value = "remark", required = false) String remark) { // 处理文件上传逻辑,比如保存到本地磁盘 if (!imageFile.isEmpty()) { try { byte[] fileBytes = imageFile.getBytes(); // 这里写你的保存逻辑,比如写到服务器的某个目录 // FileOutputStream fos = new FileOutputStream("/server/upload/" + imageFile.getOriginalFilename()); // fos.write(fileBytes); // fos.close(); return ResponseEntity.ok("图片上传成功!"); } catch (IOException e) { e.printStackTrace(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("图片保存失败"); } } else { return ResponseEntity.badRequest().body("上传的图片为空"); } } }
2. 可选:配置文件上传大小限制
如果你的图片比较大,可能需要在application.properties里设置上传大小限制:
# 单个文件最大10MB spring.servlet.multipart.max-file-size=10MB # 整个请求最大10MB spring.servlet.multipart.max-request-size=10MB
最后提醒几个容易踩的坑
- 绝对不要手动把请求的Content-Type设为
text/plain,@Multipart注解会自动帮你设置正确的multipart/form-data。 - Android端和服务器端的参数名称(比如
"file")必须完全一致,大小写也不能错,否则服务器会找不到文件参数。 - 别忘了给Android app加网络权限:
<uses-permission android:name="android.permission.INTERNET"/>,如果是从本地相册选图,还要加文件读取权限。
内容的提问来源于stack exchange,提问作者bdeane
相关产品推荐
相关产品推荐

