如何使用二进制改造上传图像?
How to upload image using retrofit in binary?
我正在开发一个 android 应用程序,其中 post 一些用户使用用户签名输入数据(使用签名板捕获签名并将其转换为 bmp 文件)。
现在,在 post 处理整个数据之前,我需要请求服务器上传我的 canvas 签名。所以服务器将回复两个 urls(参考图片 1),它们被放置 url 并得到 url 现在我必须使用 PUT url 上传签名图像文件和postman 完成了整个过程,但我无法在 android 应用程序上实现它。 Put URl 的主体是二进制的,我 select 是一些随机图像文件。
作为参考,请参阅随附的屏幕截图.
Retrofit retrofit_image_upload=new Retrofit.Builder()
.baseUrl(Aws_url) // base url retrive using Uri class using uri.getAuthority and concat with "https:/"
.addConverterFactory(GsonConverterFactory.create())
.build();
ByteArrayOutputStream stream=new ByteArrayOutputStream();
signature.compress(Bitmap.CompressFormat.PNG,100,stream);
byte[] byteArray=stream.toByteArray();
final RequestBody requestBody=RequestBody.create(MediaType.parse("application/octet-stream"),byteArray);
正在调用 api 并传递数据
Call<Object> image_upload_call= null;
try {
image_upload_call = final_upload.aws_upload(path,auth,requestBody.contentLength(),x_amz_acl,AWSAccessKeyId,Expires,Signature_aws,requestBody);
} catch (IOException e) {
e.printStackTrace();
}
上传图片的界面
@PUT("{Put_path}")
Call<Object> aws_upload(@Path("Put_path") String path,
@Header("auth") String auth,
@Header("Content-Length") long length,
@Query("x-amz-acl") String x_amz,
@Query("AWSAccessKeyId") String awskey,
@Query("Expires") String Expires,
@Query("Signature") String Awssignature,
@Body RequestBody image);
}
当我使用此代码设置服务器不接受来自 android 应用程序的文件并且响应是错误代码 403 并且当我尝试从 postman 软件上传图像文件时它工作正常.那么我如何将其实现到 android 应用程序中。
服务器错误
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
数据准备部分代码对我来说看起来还不错。但是您用于 PUT 请求的 URL 是错误的。
正如你在问题中提到的
before posting whole data I need to request server to upload my canvas signature. so server will reply with two urls
API 返回 2 URLs。在这 2 URL 中,您 select 第二个上传文件。我希望到目前为止它在 Android 部分工作正常。
现在,该上传文件了。您已经从 API 获得了完全合格的 URL 来上传文件。只需将您的 BASE_URL
替换为第二个 URL 即可。您应该使用 @Url
注释,而不是使用 @Path("Put_path")
注释。如下图,
@PUT() /* remove "{Put_path}" parameter*/
Call<Object> aws_upload(
@Url String path, /* replace @Path() with @Url */
@Header("auth") String auth,
@Header("Content-Length") long length,
@Query("x-amz-acl") String x_amz,
@Query("AWSAccessKeyId") String awskey,
@Query("Expires") String Expires,
@Query("Signature") String Awssignature,
@Body RequestBody image);
说明
- 它是如何工作的?
假设您想点击以下 URL
https://api.example.com/users/{user_id}
在 Retrofit 中,您声明一个 BASE_URL
并为其赋值 https://api.example.com/
。在你的服务接口文件中,你声明了一个如下所示的方法
@GET("users/{user_id}")
Call<UserModel> fetchUserById(@Path("user_id") int userId);
每当您调用上述方法时,它都会构建一个 URL,例如
https://api.example.com/users/100
从上面的例子中我们了解到@GET()
、@POST()
、@PUT()
、@DELETE()
等方法接受部分URL并且Retrofit客户端将为您生成完全合格的 URL。
- 如果你想从 Retrofit 客户端点击 URL 而不是 BASE_URL 怎么办?
在这种情况下,我们使用 Retrofit 的 @Url
注释。它将完全替换当前请求的 BASE_URL。
我将演示与上面相同的示例,但带有 @Url
注释。
@GET() // notice the difference you don't need to pass partial path here
Call<UserModel> fetchUserById(@Url String url);
这次我将在调用方法或 Activity/Fragment.
中对完全限定的 URL 进行硬编码
String overrideUrl = "https://api.example.com/users/200"; // prepare fully qualified url
SomeServiceInterface service = ...
Call<UserModel> call = service.fetchUserById(overrideUrl); // pass it to method as an argument
call.enqueue(/* callback implementation here */);
我正在开发一个 android 应用程序,其中 post 一些用户使用用户签名输入数据(使用签名板捕获签名并将其转换为 bmp 文件)。
现在,在 post 处理整个数据之前,我需要请求服务器上传我的 canvas 签名。所以服务器将回复两个 urls(参考图片 1),它们被放置 url 并得到 url 现在我必须使用 PUT url 上传签名图像文件和postman 完成了整个过程,但我无法在 android 应用程序上实现它。 Put URl 的主体是二进制的,我 select 是一些随机图像文件。
作为参考,请参阅随附的屏幕截图
Retrofit retrofit_image_upload=new Retrofit.Builder()
.baseUrl(Aws_url) // base url retrive using Uri class using uri.getAuthority and concat with "https:/"
.addConverterFactory(GsonConverterFactory.create())
.build();
ByteArrayOutputStream stream=new ByteArrayOutputStream();
signature.compress(Bitmap.CompressFormat.PNG,100,stream);
byte[] byteArray=stream.toByteArray();
final RequestBody requestBody=RequestBody.create(MediaType.parse("application/octet-stream"),byteArray);
正在调用 api 并传递数据
Call<Object> image_upload_call= null;
try {
image_upload_call = final_upload.aws_upload(path,auth,requestBody.contentLength(),x_amz_acl,AWSAccessKeyId,Expires,Signature_aws,requestBody);
} catch (IOException e) {
e.printStackTrace();
}
上传图片的界面
@PUT("{Put_path}")
Call<Object> aws_upload(@Path("Put_path") String path,
@Header("auth") String auth,
@Header("Content-Length") long length,
@Query("x-amz-acl") String x_amz,
@Query("AWSAccessKeyId") String awskey,
@Query("Expires") String Expires,
@Query("Signature") String Awssignature,
@Body RequestBody image);
}
当我使用此代码设置服务器不接受来自 android 应用程序的文件并且响应是错误代码 403 并且当我尝试从 postman 软件上传图像文件时它工作正常.那么我如何将其实现到 android 应用程序中。 服务器错误
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
数据准备部分代码对我来说看起来还不错。但是您用于 PUT 请求的 URL 是错误的。
正如你在问题中提到的
before posting whole data I need to request server to upload my canvas signature. so server will reply with two urls
API 返回 2 URLs。在这 2 URL 中,您 select 第二个上传文件。我希望到目前为止它在 Android 部分工作正常。
现在,该上传文件了。您已经从 API 获得了完全合格的 URL 来上传文件。只需将您的 BASE_URL
替换为第二个 URL 即可。您应该使用 @Url
注释,而不是使用 @Path("Put_path")
注释。如下图,
@PUT() /* remove "{Put_path}" parameter*/
Call<Object> aws_upload(
@Url String path, /* replace @Path() with @Url */
@Header("auth") String auth,
@Header("Content-Length") long length,
@Query("x-amz-acl") String x_amz,
@Query("AWSAccessKeyId") String awskey,
@Query("Expires") String Expires,
@Query("Signature") String Awssignature,
@Body RequestBody image);
说明
- 它是如何工作的?
假设您想点击以下 URL
https://api.example.com/users/{user_id}
在 Retrofit 中,您声明一个 BASE_URL
并为其赋值 https://api.example.com/
。在你的服务接口文件中,你声明了一个如下所示的方法
@GET("users/{user_id}")
Call<UserModel> fetchUserById(@Path("user_id") int userId);
每当您调用上述方法时,它都会构建一个 URL,例如
https://api.example.com/users/100
从上面的例子中我们了解到@GET()
、@POST()
、@PUT()
、@DELETE()
等方法接受部分URL并且Retrofit客户端将为您生成完全合格的 URL。
- 如果你想从 Retrofit 客户端点击 URL 而不是 BASE_URL 怎么办?
在这种情况下,我们使用 Retrofit 的 @Url
注释。它将完全替换当前请求的 BASE_URL。
我将演示与上面相同的示例,但带有 @Url
注释。
@GET() // notice the difference you don't need to pass partial path here
Call<UserModel> fetchUserById(@Url String url);
这次我将在调用方法或 Activity/Fragment.
中对完全限定的 URL 进行硬编码String overrideUrl = "https://api.example.com/users/200"; // prepare fully qualified url
SomeServiceInterface service = ...
Call<UserModel> call = service.fetchUserById(overrideUrl); // pass it to method as an argument
call.enqueue(/* callback implementation here */);