ben*_*n10 2 android header multipart retrofit retrofit2
我的界面是这样的
@Multipart
@NonNull
@FormUrlEncoded
@POST("upload")
Call<GeneralResponse> uploadImage(@Header("Authorization") MultipartBody.Part token, @Part("image") MultipartBody.Part image, @Part("kilometer") MultipartBody.Part distance);
Run Code Online (Sandbox Code Playgroud)
上传图片和数据的方法
public void upload(final String token,final String distance, final File image) {
InternetConnection internetConnection = new InternetConnection(TimeCard.this);
if (internetConnection.isConnectingToInternet()) {
showProgressDialog();
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
MultipartBody.Part bodykm;
RequestBody kilometer;
kilometer= RequestBody.create(MediaType.parse("text/plain"), distance);
bodykm =MultipartBody.Part.createFormData("kilometer", distance, kilometer);
Call<GeneralResponse> call = apiService.uploadImage(token,bodyImage,bodykm);
call.enqueue(new Callback<GeneralResponse>() {
@Override
public void onResponse(Call<GeneralResponse> call, final Response<GeneralResponse> response) {
try {
if(response.body().getStatus()){
meterImage = "";
distanceKm = "";
Toast.makeText(TimeCard.this,response.body().getMessage(),Toast.LENGTH_LONG).show();
}else {
Toast.makeText(TimeCard.this,response.body().getMessage(),Toast.LENGTH_LONG).show();
}
}catch (Exception e){
progressDialog.dismiss();
e.printStackTrace();
Toast.makeText(TimeCard.this,e.getMessage(),Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<GeneralResponse> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(TimeCard.this,"Server error please try again later",Toast.LENGTH_LONG).show();
}
});
} else {
Toast.makeText(TimeCard.this,"Please check your internet connection",Toast.LENGTH_LONG).show();
}
}
Run Code Online (Sandbox Code Playgroud)
它给出了错误,因为只允许一种类型的注释。所以我将 @Header 更改为 @Part
@Multipart
@NonNull
@FormUrlEncoded
@POST("upload")
Call<GeneralResponse> uploadImage(@Part("Authorization") MultipartBody.Part token, @Part("image") MultipartBody.Part image, @Part("kilometer") MultipartBody.Part distance);
Run Code Online (Sandbox Code Playgroud)
现在我如何传递标题?(如何将标头转换为 MultipartBody.Part?)
我先回答你的问题
它给出错误,因为只允许一种类型的注释
是的,这是 Retrofit 的预期行为。您不能一次使用多个注释。因此,只需@FormUrlEncoded从中删除注释uploadImage()方法中。
现在,您需要与图像一起发布距离。为此,您应该使用如下所示的内部uploadImage()方法(在服务类中)。
@Part("kilometer") RequestBody distance // note: use RequestBody instead of MultipartBody.Part
Run Code Online (Sandbox Code Playgroud)
内部upload()函数(在您的活动中)进行更改。
RequestBody kilometer = RequestBody.create(MediaType.parse("text/plain"), distance);
Run Code Online (Sandbox Code Playgroud)
现在来回答问题
如何在改造中使用@Part 传递标头?
我假设您拥有动态授权密钥(通过查看相关示例代码)。
如果您在运行时将动态授权密钥设置为标头,则可以使用 Retrofit 的 @HeaderMap注释。
只需在uploadImage()方法中进行以下更改即可。
@HeaderMap Map<String, String> token
Run Code Online (Sandbox Code Playgroud)
在 Activity 中准备如下标题映射。
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", token);
Run Code Online (Sandbox Code Playgroud)
如果要设置其他标头参数,请将其设置在相同的标头哈希映射中。
然后将此标题映射传递给您 uploadImage()方法。
因此,您的代码中的最终更改是这样的。
您的服务接口
@Multipart
@NonNull
@POST("upload")
Call<GeneralResponse> uploadImage(@HeaderMap Map<String, String> token, @Part("image") MultipartBody.Part image, @Part("kilometer") RequestBody distance);
Run Code Online (Sandbox Code Playgroud)
并在活动中
public void upload(final String token,final String distance, final File image) {
InternetConnection internetConnection = new InternetConnection(TimeCard.this);
if (internetConnection.isConnectingToInternet()) {
showProgressDialog();
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
// prepare distance body
RequestBody kilometer = RequestBody.create(MediaType.parse("text/plain"), distance);
// prepare headers
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", token);
Call<GeneralResponse> call = apiService.uploadImage(headers, bodyImage, kilometer);
call.enqueue(new Callback<GeneralResponse>() {
@Override
public void onResponse(Call<GeneralResponse> call, final Response<GeneralResponse> response) {
try {
if(response.body().getStatus()){
meterImage = "";
distanceKm = "";
Toast.makeText(TimeCard.this,response.body().getMessage(),Toast.LENGTH_LONG).show();
}else {
Toast.makeText(TimeCard.this,response.body().getMessage(),Toast.LENGTH_LONG).show();
}
}catch (Exception e){
progressDialog.dismiss();
e.printStackTrace();
Toast.makeText(TimeCard.this,e.getMessage(),Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<GeneralResponse> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(TimeCard.this,"Server error please try again later",Toast.LENGTH_LONG).show();
}
});
} else {
Toast.makeText(TimeCard.this,"Please check your internet connection",Toast.LENGTH_LONG).show();
}
}
Run Code Online (Sandbox Code Playgroud)
额外的
如果您有静态令牌(每个用户或 API 密钥永远不会更改的令牌),则无需在此处使用标头映射模式。只需跳过@HeaderMap注释/参数。进行如下更改。
@Headers("Authorization: your_token_key_here")
@Multipart
@NonNull
@POST("upload")
Call<GeneralResponse> uploadImage(@Part("image") MultipartBody.Part image, @Part("kilometer") RequestBody distance);
Run Code Online (Sandbox Code Playgroud)
同样,如果您有多个标题,请将标题参数括在{}大括号内。
@Headers({
"Authorization: your_token_key_here",
"Content-Type: application/json", // just an example
"some other header here"
})
@Multipart
@NonNull
@POST("upload")
Call<GeneralResponse> uploadImage(@Part("image") MultipartBody.Part image, @Part("kilometer") RequestBody distance);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2666 次 |
| 最近记录: |