[英]Error uploading file with Retrofit 2
我正在工作的系统有一个接收文件图片的端点,以便设置用户的个人资料图片。 如果我尝试通过邮递员发送,一切正常:
当我尝试使用改造从我的应用程序上载它时,它总是失败。 代码和堆栈跟踪如下:
服务器端代码:
begin
user = User.find(doorkeeper_token.resource_owner_id)
image = params[:image]
attachment = {
:filename => image[:filename],
:type => image[:type],
:headers => image[:head],
:tempfile => image[:tempfile]
}
image_link = ""
if params[:upload_type] == "profile"
user.profile_image = ActionDispatch::Http::UploadedFile.new(attachment)
image_link = get_image_path(user.id,params[:upload_type],"original",attachment[:filename])
user.image_profile_original = get_image_path(user.id,params[:upload_type],"original",attachment[:filename])
user.image_profile_large = get_image_path(user.id,params[:upload_type],"large",attachment[:filename])
/*e22*/
@Multipart
@POST("user/upload_image")
fun uploadUserImage(@Header("Authorization") authHeader: String, @Part("upload_type") description: RequestBody, @Part file: MultipartBody.Part): Call<ResponseWrapper>
fun uploadUserImage(image: Uri) {
val source = File(image.path)
val requestFile = RequestBody.create(MediaType.parse(getContext().contentResolver.getType(image)), source)
val body = MultipartBody.Part.createFormData("image", "profile", requestFile)
val description = RequestBody.create(okhttp3.MultipartBody.FORM, "profile")
mMessenger.uploadUserImage(getAuthorizationHeader(), description, body).enqueue(ResponseWrapperCallback(EventCatalog.e0022))
}
要求回复:
E/ResponseWrapperCallback: Failed processing request: profile: open failed: ENOENT (No such file or directory)
E/ResponseWrapperCallback: HTTP request mapped to event e0022 finished with error
我确实认为此错误与File对象的实例化有关。 如果我直接从Uri创建文件,则它的真实路径似乎不会发送到服务器。 我说这是因为上面的错误日志,它说它没有在检索到的设备的Uri上找到该文件。 我试图从Uri中提取文件的真实路径,但是,服务器的错误日志已更改为:
/storage/emulated/0/Marvel/Media/Characters/Adam Warlock.jpeg: open failed: EACCES (Permission denied)
我使用真实文件路径实例化File对象的方式是这样的:
private fun getRealPathFromURI(contentURI: Uri): String {
val result: String
val cursor = getContext().contentResolver.query(contentURI, null, null, null, null)
if (cursor == null) {
result = contentURI.path
} else {
cursor.moveToFirst()
val idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA)
result = cursor.getString(idx)
cursor.close()
}
return result
}
//....
val source = File(getRealPathFromURI(Uri))
根据用户Anurag Singh的请求,以下是清单和操作系统信息:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
android {
compileSdkVersion 25
buildToolsVersion "25.0.1"
defaultConfig {
applicationId "***"
minSdkVersion 16
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
vectorDrawables.useSupportLibrary = true
}
}
这是Postman生成的代码,效果很好!
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
RequestBody body = RequestBody.create(mediaType, "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"image\"; filename=\"sample 2.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"upload_type\"\r\n\r\nprofile\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--");
Request request = new Request.Builder()
.url("http://********/user/upload_image")
.post(body)
.addHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
.addHeader("authorization", "Bearer ******")
.addHeader("cache-control", "no-cache")
.addHeader("postman-token", "******")
.build();
Response response = client.newCall(request).execute();
尝试在AndroidManifest.xml
添加以下权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>.
从Android 6.0(API级别23)开始,用户在应用程序运行时(而不是在安装应用程序时)授予应用程序权限。 在运行时请求权限
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.