我的界面就是这样
@Multipart
@NonNull
@FormUrlEncoded
@POST("upload")
Call<GeneralResponse> uploadImage(@Header("Authorization") MultipartBody.Part token, @Part("image") MultipartBody.Part image, @Part("kilometer") MultipartBody.Part distance);
上传图像和数据的方法
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();
}
}
它给出了错误,因为只允许一种类型的注释。所以我将@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);
现在如何传递标头? (如何将标头转换为MultipartBody.Part?)
答案 0 :(得分:4)
我将从回答您的问题开始
由于只允许一种类型的注释,因此会出错
是的,这是改造的预期行为。您不能一次使用多个注释。因此,只需从@FormUrlEncoded
方法中删除uploadImage()
注释。
现在,您要发布距离以及图像。为此,您应该在uploadImage()
方法(在服务类中)内部使用以下代码。
@Part("kilometer") RequestBody distance // note: use RequestBody instead of MultipartBody.Part
在upload()
函数(在“活动”中)中进行更改。
RequestBody kilometer = RequestBody.create(MediaType.parse("text/plain"), distance);
现在开始提问
如何在改造中使用@Part传递标头?
我假设您具有动态授权密钥(通过查看有问题的示例代码)。
如果在运行时将动态授权密钥设置为标头,则可以使用Retrofit的@HeaderMap
批注。
只需在uploadImage()
方法中进行以下更改。
@HeaderMap Map<String, String> token
内部活动准备标题映射如下。
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", token);
如果要设置其他标头参数,请在同一标头哈希图中进行设置。
然后将此标头映射传递到您的uploadImage()
方法。
因此,代码中的最终更改是这样的。
您的服务界面
@Multipart
@NonNull
@POST("upload")
Call<GeneralResponse> uploadImage(@HeaderMap Map<String, String> token, @Part("image") MultipartBody.Part image, @Part("kilometer") RequestBody distance);
和活动
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();
}
}
额外
如果您具有静态令牌(每个用户或API密钥永不更改的令牌),则无需在此处使用标头映射模式。只需跳过@HeaderMap
注释/参数。进行如下更改。
@Headers("Authorization: your_token_key_here")
@Multipart
@NonNull
@POST("upload")
Call<GeneralResponse> uploadImage(@Part("image") MultipartBody.Part image, @Part("kilometer") RequestBody distance);
同样,如果您有多个标头,请将标头参数放在{}
大括号内。
@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);