【问题标题】:Send Image file via Retrofit from Android to Spring通过 Retrofit 从 Android 向 Spring 发送图像文件
【发布时间】:2019-04-19 23:10:01
【问题描述】:

我正在尝试通过 Spring 将图像通过 Retrofit 上传到 S3。所以,基本上是两个任务。

  1. 将图像传递给 Spring API
  2. 从 Spring API 将其上传到 S3 服务器。

我知道如何将图像上传到 S3,它工作正常。

我的问题是第一部分。我在网上尝试了很多解决方案,但没有奏效。这是我的代码 ->

在 Android 端,首先我要获取文件并将其上传到 Spring API ->

private void UploadFiles() {
        File uploadFile = fileArrayList.get(0);
        if (uploadFile != null) {
            Log.d(TAG, "UploadFiles: File Name is -> " + uploadFile.getName());
            RequestBody requestFile = RequestBody.create(MediaType.parse("image/*"), uploadFile);
            MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("image", uploadFile.getName(), requestFile);
            cropImageRequest.setCropId(uploadFile.getParent());
            cropImageRequest.setCropImage(multipartBody);
            FarmerResponse farmerResponse = UserAuth.getInstance(this).getCurrentUser();
            Api.uploadCropImage(farmerResponse.getAuthToken(), farmerResponse.getFarmer().getId(), cropImageRequest, new Callback<BasicResponse>() {
                @Override
                public void onResponse(Call<BasicResponse> call, Response<BasicResponse> response) {
                    Log.d(TAG, "onResponse: Success : " + response.toString());
                }

                @Override
                public void onFailure(Call<BasicResponse> call, Throwable t) {
                    Log.d(TAG, "onResponse: Failure : " + t.getMessage());
                }
            });
        }
    }

我创建了一个cropImageRequest.java,它基本上是Request Body 的一个POJO 类。这是我的 POJO 类,它包含 Image 和 ImageId。 ->

import okhttp3.MultipartBody;

public class CropImageRequest {

    private String CropId;
    private MultipartBody.Part CropImage;

    public CropImageRequest() {

    }

    public void setCropId(String cropId) {
        CropId = cropId;
    }

    public void setCropImage(MultipartBody.Part cropImage) {
        CropImage = cropImage;
    }

    public CropImageRequest(String cropId, MultipartBody.Part cropImage) {
        CropId = cropId;
        CropImage = cropImage;
    }

    public String getCropId() {
        return CropId;
    }

    public MultipartBody.Part getCropImage() {
        return CropImage;
    }
}

这是我的 API 声明,在 API 类中。 ->

public interface UploadCropImageApi {
        @POST(UPLOAD_FILE_TO_AWS_URL)
        Call<BasicResponse> uploadCropImage(
                @Header(MOBILE_AUTH) String authToken,
                @Header(FARMER_ID) String farmerId,
                @Body CropImageRequest cropImageRequest);
    }
        public static void uploadCropImage(String authToken, String farmerId, CropImageRequest cropImageRequest, Callback<BasicResponse> callback) {
                UploadCropImageApi uploadCropImageApi = retrofit.create(UploadCropImageApi.class);
                Call<BasicResponse> call = uploadCropImageApi.uploadCropImage(authToken, farmerId, cropImageRequest);
                call.enqueue(callback);
    }

在 Spring 方面,我开发了一个控制器,它处理 API 请求并将传递的图像上传到 S3 ->

@RequestMapping(value = "/UploadCropImage",method = RequestMethod.POST,produces = "application/json")
    @ResponseBody
    public String UploadImage(@RequestBody CropImageRequest cropImageRequest,HttpServletRequest request) {
        uuid = new UUIDUtils();
        fileUtils = new FileUtils();
        try {
            String KeyName = uuid.GenerateUUID(fileUtils.convert(cropImageRequest.getCropImage()));
            System.out.println(KeyName);
            return mAmazonClient.uploadImage(KeyName,cropImageRequest.getCropImage());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }

这是我将 MultiPart 文件转换为文件的 Convert 函数。

public String convert(MultipartFile file) throws IOException {
        if(file!=null){
            File convFile = new File(file.getOriginalFilename());
            convFile.createNewFile();
            FileOutputStream fos = new FileOutputStream(convFile);
            fos.write(file.getBytes());
            fos.close();
            return convFile.getName();
        }
        else{
            System.out.println("Supplied File is null");
            return null;
        }       
    }

问题是我得到空指针异常,在 Spring 方面,条件检查。这意味着文件没有被上传。在 Android 端,我通过打印出文件名进行了验证,并且打印了正确的文件名。顺便说一句,我正在上传 .WebP 格式的文件,我认为这不会造成任何问题。提前感谢您的帮助。

【问题讨论】:

    标签: java android spring amazon-s3 retrofit2


    【解决方案1】:

    您正在使用 multipart/form-data 发送您的信息 所以尝试使用

    @ModelAttribute

    而不是

    @RequestBody

    方法签名将是

    public String UploadImage(@ModelAttribute CropImageRequest cropImageRequest,HttpServletRequest request)
    

    【讨论】:

    • 我只想通过请求正文发送数据,因为 Spring 已加密请求正文,是的,我已将代码更改为发送“image/*”而不是“multipart/form-data”。
    • 如果你使用的是图像/* 整个身体将被视为图像,如果是这样,只发送图像并更改您的方法签名以获得MultipartFile文件
    • 我是 spring 新手,你能告诉我如何在 RequestBody 中发送这个 POJO 吗?
    • 您能确保按上述方式编辑您的代码吗?您将能够在里面发送 POJO
    • 但是您使用的是 ModelAttribute 而不是 requestBody。我不希望这样,我尝试用 RequestBody 替换 ModelAttribute。它没有用。
    猜你喜欢
    • 2015-09-15
    • 2016-03-14
    • 2015-01-28
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 2018-08-26
    相关资源
    最近更新 更多