问题
Im about to start crying, because Ive tried many solutions and topics, but it doesn`t work.
The issue: I have to upload an String (it was a bitmap, but I have base64 coded) to our lovely server, so I have created a background Thread in Android to do it, and calling the backend. I get a HTTP 400 error message, with the following message:
org.springframework.web.bind.MissingServletRequestParameterException","message":"Required MultipartFile parameter 'file' is not present","path":"/backend/newimage"}.
My headers:
Content-Disposition: form-data; name="file"
Content-Type: text/plain; charset=UTF-8
Content-Length: 24069
Content-Transfer-Encoding: binary
/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAA0JCgsK.......etc.....binary
I don`t see in headers the following part:
enctype: "multipart/form-data”). and I don`t understand why, my retforit interce looks like this:
@POST("/newimage")
@Multipart
String uploadImageToIdea(@Query("id") String id, @Part("file") String file );
I don`t understand the error message, because I HAVE the file param here.
I had tried the following (didn`t work obviously:
- Retrofit Multipart Upload Image failed
- Retrofit - @Body parameters cannot be used with form or multi-part encoding (added @Headers, in this case I had more header before my request, but didn`t changed anything.)
my code to call the backend (not the final version, but first let things make work :) ):
new Thread() {
@Override
public void run() {
MultipartTypedOutput file = new MultipartTypedOutput();
for (int i = 0; i < imagesToUpload.size(); ++i) {
Bitmap imageBitmap = imagesToUpload.get(i);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 60, stream);
byte[] byteArray = stream.toByteArray();
String bitmapString = Base64.encodeToString(byteArray, Base64.DEFAULT);
backend.uploadImageToIdea(submitIdeaResponse.getIdeaDetails().getId(), bitmapString);
}
}
}.start();
Note from my backend developer:
You need to send a multipart request (enctype="multipart/form-data”).
So, can someone please help me out, why I have HTTP 400 with the error message above? What can I change in my code to make this call work ? Thank you
回答1:
You should use TypedFile for sending file in Multipart.
@Multipart
@POST("/newimage")
String uploadImageToIdea(@Part("id") TypedString id, @Part("file") TypedFile file);
for more information link.
回答2:
I had this exact issue for some time. Understanding the working code below should help you resolve this.
Retrofit
@Multipart @POST("/gifts")
void save( @Part("gift") Gift gift,
@Part("file") TypedFile file,
Callback<Resource<Gift>> callback);
Spring
@RequestMapping(value="/gifts", method=RequestMethod.POST)
public @ResponseBody HttpEntity<Gift> addGift(
@RequestPart Gift gift,
@RequestPart MultipartFile file) {...}
Note Spring will use reflection to match part names with controller method parameters. So the parameter file should match part "file". You can always override this in Spring by adding the part name manually: @RequestPart("file")
Example Call:
service.save(gift, typedFile, new Callback<Resource<Gift>>() {
@Override
public void success(Resource<Gift> resources, Response response)
{/*...*/}
@Override
public void failure(RetrofitError error)
{/* ... */}
});
Tip; don't mix multipart request with query strings unless you want a headache. Matching parts with parts seems to work well from one platform to another.
回答3:
Okay, I have figured out the solution:
for (int i = 0; i < imagesToUpload.size(); ++i) {
Bitmap imageBitmap = imagesToUpload.get(i);
try {
String fileNameWithPath = getCacheDir().getAbsolutePath() + "file_" + String.valueOf(i);
FileOutputStream out = new FileOutputStream(fileNameWithPath);
imageBitmap.compress(Bitmap.CompressFormat.PNG, 60, out);
out.close();
backend.uploadImageToIdea(submitIdeaResponse.getIdeaDetails().getId(), new TypedFile("multipart/form-data",new File(fileNameWithPath)));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
and the retrofit interface is the following:
@POST("/newimage")
@Multipart
String uploadImageToIdea(@Part ("id") String id, @Part("file") TypedFile file );
So I don`t base64Code the image and uploading from the memory, BUT saving into the cache dir and upload the file itself. Using TypeFile of Retrofit for it.
来源:https://stackoverflow.com/questions/31121212/retrofit-and-multipart-image-uploading-with-http-400