如何在改造中使用 @Part 传递 header?
how can I pass header using @Part in retrofit?
我的界面是这样的
@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();
}
}
它给出错误,因为只有一种类型的注释是 allowed.so 我将 @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);
现在我怎样才能通过header? (如何将header转换为MultipartBody.Part?)
我先回答你的问题
it gives error because only one type of annotation is allowed
是的,这是 Retrofit 的预期行为。您不能一次使用多个注释。因此,只需从 uploadImage()
方法中删除 @FormUrlEncoded
注释。
现在,您需要 post 距离 以及图像。为此,您应该在 uploadImage()
方法中使用如下所示(在服务 class 中)。
@Part("kilometer") RequestBody distance // note: use RequestBody instead of MultipartBody.Part
并在 upload()
函数内(在您的 Activity 中)进行更改。
RequestBody kilometer = RequestBody.create(MediaType.parse("text/plain"), distance);
现在进入问题
how can I pass header using @Part in retrofit?
我假设您有动态授权密钥(通过查看相关示例代码)。
如果您在运行时将动态授权密钥设置为 header,您可以使用 Retrofit 的 @HeaderMap
注释。
只需在 uploadImage()
方法中进行以下更改。
@HeaderMap Map<String, String> token
在 Activity 中准备 header 如下图。
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", token);
如果要设置其他 header 参数,请将其设置在同一个 headers 哈希映射中。
然后将此 header 映射传递给您的 uploadImage()
方法。
因此,您的代码中的最终更改如下所示。
您的服务界面
@Multipart
@NonNull
@POST("upload")
Call<GeneralResponse> uploadImage(@HeaderMap Map<String, String> token, @Part("image") MultipartBody.Part image, @Part("kilometer") RequestBody distance);
并在 Activity
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 密钥从不更改的令牌),则无需在此处使用 header 映射模式。直接跳过 @HeaderMap
annotation/parameter。进行如下更改。
@Headers("Authorization: your_token_key_here")
@Multipart
@NonNull
@POST("upload")
Call<GeneralResponse> uploadImage(@Part("image") MultipartBody.Part image, @Part("kilometer") RequestBody distance);
同样,如果您有多个 header,请将 header 参数括在 {}
大括号内。
@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);
我的界面是这样的
@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();
}
}
它给出错误,因为只有一种类型的注释是 allowed.so 我将 @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);
现在我怎样才能通过header? (如何将header转换为MultipartBody.Part?)
我先回答你的问题
it gives error because only one type of annotation is allowed
是的,这是 Retrofit 的预期行为。您不能一次使用多个注释。因此,只需从 uploadImage()
方法中删除 @FormUrlEncoded
注释。
现在,您需要 post 距离 以及图像。为此,您应该在 uploadImage()
方法中使用如下所示(在服务 class 中)。
@Part("kilometer") RequestBody distance // note: use RequestBody instead of MultipartBody.Part
并在 upload()
函数内(在您的 Activity 中)进行更改。
RequestBody kilometer = RequestBody.create(MediaType.parse("text/plain"), distance);
现在进入问题
how can I pass header using @Part in retrofit?
我假设您有动态授权密钥(通过查看相关示例代码)。
如果您在运行时将动态授权密钥设置为 header,您可以使用 Retrofit 的 @HeaderMap
注释。
只需在 uploadImage()
方法中进行以下更改。
@HeaderMap Map<String, String> token
在 Activity 中准备 header 如下图。
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", token);
如果要设置其他 header 参数,请将其设置在同一个 headers 哈希映射中。
然后将此 header 映射传递给您的 uploadImage()
方法。
因此,您的代码中的最终更改如下所示。
您的服务界面
@Multipart
@NonNull
@POST("upload")
Call<GeneralResponse> uploadImage(@HeaderMap Map<String, String> token, @Part("image") MultipartBody.Part image, @Part("kilometer") RequestBody distance);
并在 Activity
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 密钥从不更改的令牌),则无需在此处使用 header 映射模式。直接跳过 @HeaderMap
annotation/parameter。进行如下更改。
@Headers("Authorization: your_token_key_here")
@Multipart
@NonNull
@POST("upload")
Call<GeneralResponse> uploadImage(@Part("image") MultipartBody.Part image, @Part("kilometer") RequestBody distance);
同样,如果您有多个 header,请将 header 参数括在 {}
大括号内。
@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);