Android Java使用OkHttp上传图片至服务器失败:仅图片名称上传成功
Android Java使用OkHttp上传图片至服务器失败:仅图片名称上传成功
看起来你遇到了OkHttp上传图片时的典型问题——文件名能成功传到服务器,但图片内容却没传过去,我来帮你排查几个常见原因并给出修复方案:
一、先排查最基础的文件和权限问题
首先要确认你传入的picturePath对应的文件确实存在且可读:
- 在调用
connectServer方法前,先加个检查:if (!picturePath.exists() || !picturePath.canRead()) { Toast.makeText(this, "文件不存在或无法读取", Toast.LENGTH_SHORT).show(); return; } - 别忘了权限配置:如果是读取外部存储的图片,Android 6.0+需要动态申请
READ_EXTERNAL_STORAGE权限;Android 10+要注意适配Scoped Storage,避免直接访问文件路径(如果是从相册选图,建议用Uri配合ContentResolver处理)。
二、修复OkHttp的超时与请求配置
你的代码注释掉了超时设置,上传图片时如果网络不稳定,默认超时时间可能不够导致上传中断,另外要正确获取服务器返回的响应内容来定位问题:
修改OkHttpClient的创建和响应处理部分:
try { // 设置足够的超时时间,避免大图片上传超时 OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(60, TimeUnit.SECONDS) .readTimeout(60, TimeUnit.SECONDS) .writeTimeout(60, TimeUnit.SECONDS) .build(); Response response = client.newCall(request).execute(); // 正确获取响应体内容,而不是打印Response对象本身 if (response.isSuccessful()) { String result = response.body().string(); Toast.makeText(this, "上传响应:" + result, Toast.LENGTH_LONG).show(); } else { String errorMsg = response.code() + " - " + response.body().string(); Toast.makeText(this, "上传失败:" + errorMsg, Toast.LENGTH_LONG).show(); } } catch (Exception e) { // 打印异常日志,方便排查 e.printStackTrace(); Toast.makeText(this, "上传出错:" + e.getMessage(), Toast.LENGTH_SHORT).show(); }
三、检查Multipart请求的MediaType与字段匹配
- 确保你上传的图片确实是JPEG格式,如果是PNG或其他格式,要对应修改
MediaType.parse("image/jpeg")为image/png或image/*(更通用)。 - 确认服务器端接收的文件字段名是
image,和你代码里addFormDataPart("image", ...)的第一个参数一致,很多时候服务器端字段名不匹配会导致只收到文件名。
四、特殊场景:Android 10+的文件访问限制
如果你是通过相册选择的图片,可能拿到的Uri无法直接转换为真实File路径(Scoped Storage限制),这种情况建议用输入流来构建RequestBody:
// 假设你拿到的是图片Uri Uri imageUri = ...; String fileName = "your_image_name.jpg"; RequestBody imageRequestBody = RequestBody.create( MediaType.parse("image/jpeg"), new InputStreamRequestBody(getContentResolver().openInputStream(imageUri)) ); RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("image", fileName, imageRequestBody) .addFormDataPart("name", fileName) .build();
(需要自定义InputStreamRequestBody类,实现RequestBody的writeTo方法,把输入流写入输出流即可)
最后提醒
如果客户端检查完都没问题,记得去确认服务器端的代码:是否正确解析了Multipart请求中的文件内容,有没有忽略文件流的读取逻辑。
备注:内容来源于stack exchange,提问作者code demon
相关产品推荐
相关产品推荐

