使用HTTP 400进行改造和多部分图像上传

时间:2015-06-29 16:48:50

标签: android file-upload retrofit bad-request

我即将开始哭泣,因为我尝试了很多解决方案和主题,但它不起作用。

问题: 我必须上传一个字符串(它是一个位图,但我有base64编码)到我们可爱的服务器,所以我在Android中创建了一个后台线程来执行它,并调用后端。我收到HTTP 400错误消息,并显示以下消息:

org.springframework.web.bind.MissingServletRequestParameterException","message":"Required MultipartFile parameter 'file' is not present","path":"/backend/newimage"}.

我的标题:

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

我不会在标题中看到以下部分:

  

enctype:“multipart / form-data”)。   而且我不明白为什么,我的翻版实习看起来像这样:

@POST("/newimage")
@Multipart
String uploadImageToIdea(@Query("id") String id, @Part("file") String file );

我不理解错误消息,因为我在这里有文件参数。

我曾尝试过以下方法(显然没有工作:

我的代码调用后端(不是最终版本,但首先让事情变得有效:)):

   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();

我的后端开发人员注意:

  

您需要发送多部分请求(enctype =“multipart / form-data”)。

那么,有人可以帮助我,为什么我的HTTP 400上面有错误信息?我可以在代码中更改哪些内容以使此调用有效? 谢谢

3 个答案:

答案 0 :(得分:1)

您应该使用TypedFile在Multipart中发送文件。

@Multipart
@POST("/newimage")
String uploadImageToIdea(@Part("id") TypedString id, @Part("file") TypedFile file);

了解更多信息link

答案 1 :(得分:1)

我有这个确切的问题已经有一段时间了。了解下面的工作代码可以帮助您解决此问题。

<强>改造

@Multipart @POST("/gifts")
void save( @Part("gift") Gift gift,
           @Part("file") TypedFile file,
           Callback<Resource<Gift>> callback);

<强>弹簧

@RequestMapping(value="/gifts", method=RequestMethod.POST)
public @ResponseBody HttpEntity<Gift> addGift(
        @RequestPart Gift gift,
        @RequestPart MultipartFile file) {...}

注意Spring将使用反射将部件名称与控制器方法参数匹配。因此参数 file 应匹配部分“file”。您可以通过手动添加零件名称来在Spring中覆盖它: @RequestPart(“file”)

示例致电:

service.save(gift, typedFile, new Callback<Resource<Gift>>() {

        @Override
        public void success(Resource<Gift> resources, Response response)
        {/*...*/}

        @Override
        public void failure(RetrofitError error)
        {/* ... */}
});

提示;不要将多部分请求与查询字符串混合,除非您想要头疼。与零件匹配的零件似乎从一个平台到另一个平台都能很好地工作。

答案 2 :(得分:0)

好的,我已经找到了解决方案:

                     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();
                        }

,改造界面如下:

    @POST("/newimage")
    @Multipart
    String uploadImageToIdea(@Part ("id") String id, @Part("file") TypedFile file );

所以我没有base64Code图像并从内存上传,但保存到缓存目录并上传文件本身。使用TypeFile of Retrofit。