无法从安卓设备上传图片至Java服务器。

5

我将尝试通过Android Retrofit + SpringMVC实现上传个人资料照片的功能,但是Java服务器无法响应Retrofit API调用。以下是相关代码:

ApiInterface

@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块中返回null。在调用该函数时,你应该检查返回值是否为null。如果是null,则不要继续执行。请修改你的代码。 - greenapps
进一步移除 ByteArrayOutputStream,直接将位图压缩到 fos 中。 - greenapps
创建一个新文件。请删除该行。 - greenapps
@greenapps 返回类型必须是 MultipartBody.Part,因为这是 API 参数的返回类型。图片可以在客户端选择和显示,问题是服务器没有响应请求。我认为这对我没有帮助。 - Almett
是的,我明白。但这将有助于使您的代码更加健壮。即使对于MultipartBody.Part类型,您也可以在那里返回null。请添加我要求的所有内容。 - greenapps
显示剩余2条评论
4个回答

5
在您的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"肯定可以工作)
参考 - 如何在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 "";
    }
}

0
请修改您的代码。
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;
}

0

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 "";
    }
}

0
  1. 首先,您应该检查Android客户端上传的文件是否正常。例如:使用压缩质量80

    imageBitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);

  2. 更改MediaType并在客户端RequestBody中进行调试
  3. 在服务器上进行调试以检查接收请求数据

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接