无法将图片从 Android 上传到 java 服务器
Posted
技术标签:
【中文标题】无法将图片从 Android 上传到 java 服务器【英文标题】:Unable to upload picture from Android to java server 【发布时间】:2018-05-08 07:09:21 【问题描述】:我一直在尝试通过 android Retrofit + SpringMVC 实现个人资料照片上传功能。 Java 服务器无法响应 Retrofit API 调用。相关代码sn-p如下:
API接口
@Multipart
@POST("user/profileImage")
Call<ResponseBody> uploadImage(@Part MultipartBody.Part image, @Part("name") RequestBody name);
上传到服务器
public void uploadToServer()
//Get retrofit client
Retrofit retrofit = ApiClient.getClient();
//Get API interface
ApiInterface apiInterface = retrofit.create(ApiInterface.class);
// Get image parts
MultipartBody.Part imageParts = bitmapToMultipart(imageBitmap);
//Get image name
RequestBody name = RequestBody.create(MediaType.parse("text/plain"), "ProfileImage");
//Call image upload API
Call<ResponseBody> call = apiInterface.uploadImage(imageParts,name);
call.enqueue(new Callback<ResponseBody>()
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response)
ResponseBody body = response.body();
@Override
public void onFailure(Call<ResponseBody> call, Throwable t)
t.printStackTrace();
);
bitmapToMultipart
public MultipartBody.Part bitmapToMultipart(Bitmap imageBitmap)
File file = null;
try
//create a file to write bitmap data
file = new File(this.getCacheDir(), "imageBitmap");
file.createNewFile();
//Convert bitmap to byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 0 /*ignored for PNG*/, bos);
byte[] bitmapdata = bos.toByteArray();
//write the bytes in file
FileOutputStream fos = new FileOutputStream(file);
fos.write(bitmapdata);
fos.flush();
fos.close();
catch(IOException e)
e.printStackTrace();
RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("upload", file.getName(), reqFile);
return body;
Java SpringMVC 控制器
@Controller
@RequestMapping("/user")
public class UserController
@RequestMapping(value = "/profileImage", method = RequestMethod.POST)
public @ResponseBody String imageUploader(@RequestParam("image") MultipartFile image, @RequestBody RequestBody name)throws Exception
return "";
问题是: 请求甚至没有到达 java 服务器。
【问题讨论】:
你的 bitmapToMultipart() 应该在那个 catch 块中return null;
。在调用该函数的地方,您应该检查返回值是否为 null。如果它为空,则不继续。请调整您的代码。
进一步删除 ByteArrayOutputStream 并将您的位图直接压缩为fos
。
file.createNewFile();
。删除该行。
@greenapps 返回类型必须是 MultipartBody.Part
因为这是 API 参数的返回类型。图片可以在客户端选择并显示,问题是服务器没有响应请求。我认为这对我没有帮助。
是的,我明白了。但它会帮助你使你的代码更健壮。即使对于 MultipartBody.Part 类型,您也可以在那里返回 null 。请添加我要求的所有内容。
【参考方案1】:
在您的 uploadToServer() 函数中,媒体类型应为“multipart/form-data”,而不是字段名称的“text/plain”...
//Get image name
RequestBody name = RequestBody.create(MediaType.parse("multipart/form-data"), "ProfileImage");
在您的 bitmapToMultipart() 函数中,媒体类型应为“multipart/form-data”。 (“image/*”也应该可以,但如果不是“multipart/form-data”肯定可以)
参考- How to Upload Image file in Retrofit 2
在你的 spring 控制器中你应该使用@RequestParam 代替@Requestbody
@Controller
@RequestMapping("/user")
public class UserController
@RequestMapping(value = "/profileImage", method = RequestMethod.POST)
public @ResponseBody String imageUploader(@RequestParam("image") MultipartFile image, @RequestParam String name)throws Exception
return "";
【讨论】:
【参考方案2】:请更换你的
RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file);
到
RequestBody reqFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
即你的 bitmapToMultipart 函数应该是这样的,
public MultipartBody.Part bitmapToMultipart(Bitmap imageBitmap)
File file = null;
try
//create a file to write bitmap data
file = new File(this.getCacheDir(), "imageBitmap");
file.createNewFile();
//Convert bitmap to byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 0 /*ignored for PNG*/, bos);
byte[] bitmapdata = bos.toByteArray();
//write the bytes in file
FileOutputStream fos = new FileOutputStream(file);
fos.write(bitmapdata);
fos.flush();
fos.close();
catch(IOException e)
e.printStackTrace();
RequestBody reqFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("upload", file.getName(), reqFile);
return body;
【讨论】:
【参考方案3】:API接口
@Multipart
@POST("user/profileImage")
Call<ResponseBody> uploadImage(@Part("image") MultipartBody.Part image, @Part("name") RequestBody name);
上传到服务器
public void uploadToServer()
//Get retrofit client
Retrofit retrofit = ApiClient.getClient();
//Get API interface
ApiInterface apiInterface = retrofit.create(ApiInterface.class);
// Get image parts
MultipartBody.Part imageParts = bitmapToMultipart(imageBitmap);
//Get image name
RequestBody name = RequestBody.create(MediaType.parse("text/plain"), "ProfileImage");
//Call image upload API
Call<ResponseBody> call = apiInterface.uploadImage(imageParts,name);
call.enqueue(new Callback<ResponseBody>()
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response)
ResponseBody body = response.body();
@Override
public void onFailure(Call<ResponseBody> call, Throwable t)
t.printStackTrace();
);
bitmapToMultipart
public MultipartBody.Part bitmapToMultipart(Bitmap imageBitmap)
ByteArrayOutputStream bos = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 0 /*ignored for PNG*/, bos);
byte[] bitmapdata = bos.toByteArray();
RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), bitmapdata);
MultipartBody.Part body = MultipartBody.Part.createFormData("upload", "name", reqFile);
return body;
Java SpringMVC 控制器
@Controller
@RequestMapping("/user")
public class UserController
@RequestMapping(value = "/profileImage", method = RequestMethod.POST)
public @ResponseBody String imageUploader(@RequestParam("image") MultipartFile image, @RequestParam String name)throws Exception
return "";
【讨论】:
【参考方案4】:-
首先你应该检查android客户端上传文件是否OK.eg:use compress quality 80
更改 MediaType 并在客户端调试 RequestBody 有数据 在服务器上调试检查接收请求数据imageBitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
【讨论】:
以上是关于无法将图片从 Android 上传到 java 服务器的主要内容,如果未能解决你的问题,请参考以下文章