I want to post an image with some data like this postman image:
Inside body:
And inside header:
And I write some code for uploading image like postman but I got this error:
okhttp3.internal.http2.ConnectionShutdownException
And here is my code as below:
File globalFileName;
RequestBody requestBody1 = RequestBody.create(MediaType.parse("*/*"), globalFileName);
MultipartBody.Part fileToUpload1 = MultipartBody.Part.createFormData("uploadFile",
globalFileName.getName(), requestBody1);
ApiConfig getResponse = AppConfig.getRetrofit().create(ApiConfig.class);
RequestBody type = RequestBody.create(MultipartBody.FORM, "documents");
RequestBody token = RequestBody.create(MultipartBody.FORM, "7220A3B7F8D2FD2C236092E0918B4EA3");
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.protocols( Collections.singletonList(Protocol.HTTP_1_1) );
Call<ServerResponse> call = getResponse.uploadFile(userToken, fileToUpload1, type, token);
call.enqueue(new Callback<ServerResponse>() {
#Override
public void onResponse(Call<ServerResponse> call, Response<ServerResponse> response) {
ServerResponse serverResponse = response.body();
Log.v(TAG, "Mahdi: Retrofit 2 onResponse: 0 " + serverResponse.toString());
}
#Override
public void onFailure(Call<ServerResponse> call, Throwable t) {
Log.e(TAG, "Mahdi: Retrofit 2 onFailure: ", t);
}
});
ApiConfig Interface code:
public interface ApiConfig {
#Multipart
#POST("/upload")
Call<ServerResponse> uploadFile(
#Header("token") String userToken,
#Part MultipartBody.Part file,
#Part("category") RequestBody documents,
#Part("token") RequestBody token
);
}
ServerResponse class code:
public class ServerResponse {
// variable name should be same as in the json response from php
#SerializedName("status")
boolean status;
#SerializedName("message")
String message;
public String getMessage() {
return message;
}
public boolean getSuccess() {
return status;
}
}
AppConfig class code:
public class AppConfig {
private static String BASE_URL = "https://taxiappapi.webfumeprojects.online";
public static Retrofit getRetrofit() {
return new Retrofit.Builder().baseUrl(AppConfig.BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
}
}
And I used this package:
implementation 'com.squareup.retrofit2:retrofit:2.6.1'
implementation 'com.squareup.retrofit2:converter-gson:2.6.1'
please help me thanks.
The correct structure for upload image retrofit like below but in your case i thing passing token causes issue
RequestBody requestBody1 = RequestBody.create(MediaType.parse("multipart/form-
data"), globalFileName);
MultipartBody.Part fileToUpload1 = MultipartBody.Part.createFormData("uploadFile",
globalFileName.getName(), requestBody1);
RequestBody type = RequestBody.create(MediaType.parse("multipart/form-data"),
"documents");
RequestBody token = RequestBody.create(MediaType.parse("multipart/form-data"),
"7220A3B7F8D2FD2C236092E0918B4EA3");
ApiConfig getResponse = AppConfig.getRetrofit().create(ApiConfig.class);
Hi Im trying to add a bearer token to a retrofit call in java, but i cant seem to pass it.
Currently Im logging in with one method and this creates a bearer token and im trying to add the token to the Get Call, but its just returning a 401 error, have I added the token to the call correctly?
#GET("diagnosis/configuration")
Call<ResponseBody> getFavourites (#Query("favourite") Boolean fave,#Header("Bearer Token") String authHeader);
#POST("auth/login")
Call<LoginResponse> postLogin (#Body LoginCredentialsBody body);
public class LoginApiStepDefinition extends TestBaseFix {
Retrofit retrofit = super.buildRetrofit(super.buildOkHttpClient());
RetrofitCallsLogin call = retrofit.create(RetrofitCallsLogin.class);
RetrofitCallsGetFavourites favecall = retrofit.create(RetrofitCallsGetFavourites.class);
private Response<LoginResponse> responseBody;
private String favouritesResponseBody;
String usernameValue;
String passwordValue;
#And("I login with {string} and {string} to return login token")
public void iLoginWithAndToReturnLoginToken(String username, String password) throws Exception {
LoginApi(username, password);
}
public String LoginApi(String username, String password) throws Exception {
usernameValue = username;
passwordValue = password;
//gets fixture ids for the dates
LoginCredentialsBody login = new LoginCredentialsBody();
login.setPassword(passwordValue);
login.setUsername(usernameValue);
String responseBody = call.postLogin(login).execute().body().toString();
String requiredString = responseBody.substring(responseBody.indexOf("=") + 1, responseBody.indexOf(","));
System.out.println(requiredString);
return token;
}
#Then("I get the list of favourites with {string} and {string}")
public void iGetTheListOfFavouritesWithAnd(String username, String password) throws Exception {
String favouritesResponseBody = favecall.getFavourites(true, LoginApi(username, password)).execute().body().toString();
System.out.println(favouritesResponseBody);
}
}
To add bearer token in retrofit, you have to create a class that implements Interceptor
public class TokenInterceptor implements Interceptor{
#Override
public Response intercept(Chain chain) throws IOException {
//rewrite the request to add bearer token
Request newRequest=chain.request().newBuilder()
.header("Authorization","Bearer "+ yourtokenvalue)
.build();
return chain.proceed(newRequest);
}
}
Now add your Interceptor class in OKHttpClient object and add that obejct in Retrofit object:
TokenInterceptor interceptor=new TokenInterceptor();
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build();
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.baseUrl("add your url here")
.addConverterFactory(JacksonConverterFactory.create())
.build();
these three class will be your final setup for all types of call
for first call(Login) you do not need to pass token and after login pass jwt as bearer token to authenticate after authentication do not need to pass
public class ApiUtils {
private static final String BASE_URL="https://abcd.abcd.com/";
public ApiUtils() {
}
public static API getApiService(String token){
return RetrofitClient.getClient(BASE_URL,token).create(API.class);
}}
2.Using ApiUtils.getapiService you can get the client ,pass jwt or bearer token
public class RetrofitClient {
public static Retrofit retrofit=null;
public static Retrofit getClient(String baseUrl, String token){
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(60,TimeUnit.SECONDS)
.connectTimeout(60,TimeUnit.SECONDS)
.addInterceptor(interceptor)
.addInterceptor(new Interceptor() {
#NotNull
#Override
public Response intercept(#NotNull Chain chain) throws IOException {
Request request=chain.request().newBuilder()
.addHeader("Authorization", "Bearer " + token)
.build();
return chain.proceed(request);
}
}).build();
if(retrofit==null||token!=null){
retrofit= new Retrofit.Builder()
.baseUrl(baseUrl)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}}
3 In this Interface you can create methods for get or post requests
public interface API {
#POST("/Api/Authentication/Login")
Call<JsonObject> login(#Body Model userdata);
#POST("/api/Authentication/ValidateSession")
Call<JsonObject> validateSession(#Body MyToken myToken);
#POST("/api/master/abcd")
Call<JsonObject> phoneDir(#Body JsonObject jsonObject);
#Multipart
#POST("/api/dash/UploadProfilePic")
Call<JsonObject> uploadProfile(#Part MultipartBody.Part part);
#FormUrlEncoded
#POST("/api/dashboard/RulesAndPolicies")
Call<JsonObject> rulesAndProcess(#Field("ct") int city);
#FormUrlEncoded
#POST("/api/dashboard/RulesAndPolicies")
Call<JsonObject> rulesAndProcess(
#Field("city") int city,
#Field("department") String department,
#Field("ctype") String ctype
);
Trying to send form data to the server via Retrofit but unable to request to the server. I want to post an image array with their data.
val builder: MultipartBody.Builder = MultipartBody.Builder().setType(MultipartBody.FORM);
builder.addFormDataPart("device_id",device_UDID)
builder.addFormDataPart("device_token",device_token)
builder.addFormDataPart("device_type","android")
builder.addFormDataPart("country_code",Constant.COUNTRY_CODE)
builder.addFormDataPart("email",signUpBean.email)
builder.addFormDataPart("mobile",signUpBean.phoneNumber)
builder.addFormDataPart("first_name",signUpBean.firstName)
builder.addFormDataPart("last_name",signUpBean.lastName)
builder.addFormDataPart("gender",signUpBean.gender)
builder.addFormDataPart("dob",signUpBean.dob)
builder.addFormDataPart("city",signUpBean.city)
builder.addFormDataPart("bike_type_id","1")
builder.addFormDataPart("bike_model",signUpBean.mfg)
builder.addFormDataPart("bike_manufacturer",signUpBean.mfg)
builder.addFormDataPart("reg_year",signUpBean.mfgYear)
builder.addFormDataPart("liecense_plate",signUpBean.licencePlateNo)
builder.addFormDataPart("bank_ac_name",signUpBean.bnkHolderName)
builder.addFormDataPart("bank_ac_number",signUpBean.bnkAccountNumber)
builder.addFormDataPart("bank_name",signUpBean.bnkName)
builder.addFormDataPart("bank_ifsc_code",signUpBean.ifscCode)
builder.addFormDataPart(
"profile_pic",
"profile" + ".jpg",
RequestBody.create(MediaType.parse("image/*"), file_profile!!)
)
builder.addFormDataPart(
"provider_documents[0][document]",
"1" + ".jpg",
RequestBody.create(MediaType.parse("image/*"), file_profile!!)
)
builder.addFormDataPart("provider_documents[0][document_id]","1")
builder.addFormDataPart("provider_documents[0][unique_id]","1")
builder.addFormDataPart("provider_documents[0][exprice_at]","2010-12-12")
val requestBody = builder.build()
observable = apiInterface.signUp2(requestBody)
I have tried many solutions but unable to post an image array with their data.
When i remove provider_documents from addFormDataPart it works fine.
// #Multipart
#POST(URLHelper.register)
fun signUp2(#Body builder: RequestBody ): Observable<Registration>
How can I send Providers_document array and it is working fine on Postman.
post this type of data from retrofit
val partMap = HashMap<String, RequestBody>()
partMap.put("device_id", createPartFromString(device_UDID));
partMap.put("device_token",createPartFromString(device_token))
partMap.put("device_type",createPartFromString("android"))
partMap.put("country_code",createPartFromString(Constant.COUNTRY_CODE))
partMap.put("email",createPartFromString(signUpBean.email))
partMap.put("mobile",createPartFromString(signUpBean.phoneNumber))
partMap.put("first_name",createPartFromString(signUpBean.firstName))
partMap.put("last_name",createPartFromString(signUpBean.lastName))
partMap.put("gender",createPartFromString(signUpBean.gender))
partMap.put("dob",createPartFromString(signUpBean.dob))
partMap.put("city",createPartFromString(signUpBean.city))
partMap.put("bike_type_id",createPartFromString("1"))
partMap.put("bike_model",createPartFromString(signUpBean.mfg))
partMap.put("bike_manufacturer",createPartFromString(signUpBean.mfg))
partMap.put("reg_year",createPartFromString(signUpBean.mfgYear))
partMap.put("liecense_plate",createPartFromString(signUpBean.licencePlateNo))
partMap.put("bank_ac_name",createPartFromString(signUpBean.bnkHolderName))
partMap.put("bank_ac_number",createPartFromString(signUpBean.bnkAccountNumber))
partMap.put("bank_name",createPartFromString(signUpBean.bnkName))
partMap.put("bank_ifsc_code",createPartFromString(signUpBean.ifscCode))
partMap.put(
"provider_documents["+0+"][document_id]",
createPartFromString(signUpBean.ifscCode)
)
partMap.put(
"provider_documents["+0+"][unique_id]",
createPartFromString(signUpBean.ifscCode)
)
partMap.put(
"provider_documents["+0+"][exprice_at]",createPartFromString(signUpBean.dob)
)
val ImageMap = HashMap<String, MultipartBody.Part>()
ImageMap.put("profile_pic", prepareFilePart("12", file_profile!!));
ImageMap.put("provider_documents["+0+"][document]", prepareFilePart("1", file_profile!!));
Request Api
#Multipart
#POST(URLHelper.register)
fun signUp3(
#PartMap photo: HashMap<String,
RequestBody>,
#PartMap ImageMap:HashMap<MultipartBody.Part>,
): Observable<Registration>
Dummy api interface.
public interface ApiInterface {
#Multipart
#POST(URLHelper.register)
Call<ModelProp> signUp2(#Part List<MultipartBody.Part> photos,
#PartMap Map<String, RequestBody> map;
}
Now create data to post like this.
Map<String, RequestBody> partMap = new HashMap<>();
List<MultipartBody.Part> images = new ArrayList<>();
partMap.put("device_id", createPartFromString(deviceId)); // add data which are common for all images like device_id, device_token, device_type etc.
..
..
for (int i=0; i < upFileList.size(); i++){
images.add(prepareFilePart("provider_documents["+i+"][document]", imageFile));
partMap.add("provider_documents["+i+"][expires_at]", createPartFromString(expiry)); // add image specific data.
...
..
}
...
..
observable = apiInterface.signUp2(images, partMap).
createPartFromString method
public RequestBody createPartFromString(String string) {
return RequestBody.create(MultipartBody.FORM, string);
}
prepareFilePart method
private MultipartBody.Part prepareFilePart(String partName, File file){
RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
return MultipartBody.Part.createFormData(partName, file.getName(),requestBody);
}
Use it Like this:-
// #Multipart
#POST(URLHelper.register)
fun signUp2(#Part builder: MultipartBody ): Observable<Registration>
Updated :-
private void uploadToServer(String filePath) {
showProgressDialog();
Retrofit retrofit = RetrofitClient.getRetrofitClient(this);
ApiInterface uploadAPIs = retrofit.create(ApiInterface.class);
File file = new File(filePath);
//compressor.setDestinationDirectoryPath()
RequestBody fileReqBody = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part part = MultipartBody.Part.createFormData("fileUpload", file.getName(), fileReqBody);
//RequestBody description = RequestBody.create(MediaType.parse("text/plain"), "image-type");
RequestBody imgNameReqBody = RequestBody.create(MediaType.parse("multipart/form-data"), "B2B_" + System.nanoTime());
uploadAPIs.uploadImage(imgNameReqBody, part).enqueue(new Callback<UploadImageRespose>() {
#Override
public void onResponse(#NonNull Call<UploadImageRespose> call, #NonNull retrofit2.Response<UploadImageRespose> response) {
if (response.isSuccessful() && response.body() != null) {
if (response.body().getCODE().equalsIgnoreCase("SUCCESS")) {
Toast.makeText(Activity.this, "Profile Image Upload Succesfully", Toast.LENGTH_SHORT).show();
} else {
hideProgressDialog();
Toast.makeText(Activity.this, "Some Error occurred, try again", Toast.LENGTH_SHORT).show();
}
} else {
hideProgressDialog();
}
}
#Override
public void onFailure(#NonNull Call<UploadImageRespose> call, #NonNull Throwable t) {
Timber.d(TAG, t.getMessage());
hideProgressDialog();
Toast.makeText(Activity.this, "Some Error occurred, try again", Toast.LENGTH_SHORT).show();
}
});
}
add below method in your interface:-
#Multipart
#POST("Your Path Here")
Call<UploadImageRespose> uploadImage(#Part("img_name") RequestBody img_name,
#Part MultipartBody.Part file);
I am using Part 1 code to call an API that run successfully but I want to implement the logic with Retrofit2. I have done implementation in Part 2 but code always comes with response FORBIDDEN.
The URL takes text file as byte array for uploading. Can any one have a look at the code and guide me what I am doing wrong
Part 1
public void testcall(byte[] bytesArray) {
OkHttpClient client = new OkHttpClient();
RequestBody formBody = RequestBody.create(MediaType.parse("application/json") , bytesArray);
Request request = new Request.Builder()
.url("https://logs-01.loggly.com/bulk/Token/tag/file_uploadTest")
.post(formBody)
.build();
Response response = client.newCall(request).execute();
}
Part 2
public interface ApplicationLog {
#POST("/")
LogResponse uploadLog(#Body RequestBody body);
}
public class ApplicationLogSender {
private String url;
public ApplicationLogSender(String url) {
this.url = url;
}
public ApplicationLog applicationLogSenderBuilder() {
System.out.println("Log url" + url);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(JacksonConverterFactory.create())
.build();
return retrofit.create(ApplicationLog.class);
}
}
public void testcall(byte[] bytesArray) {
RequestBody formBody = RequestBody.create(MediaType.parse("application/json") , bytesArray);
// I also tried with "Text/plain but no success"
LogResponse = builder.uploadLog(formBody).enqueue // This line always throw Forbidden
}
I want POST data from android to server, my server language is PHP.
When POST data, this data save with strange characters , such as this : وب تیØÛŒ . this data is utf8 characters and this data is not OK!. For requests i use Retrofit2
My POST request is :
private void sendComment(String cmPostID, String name, String email, String content) {
Gson gson = new GsonBuilder()
.setLenient()
.create();
OkHttpClient client = new OkHttpClient();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
Retrofit_ApiInterface requestInterface = retrofit.create(Retrofit_ApiInterface.class);
comment = new Comment();
comment.setComment_post_ID(cmPostID);
comment.setComment_author(name);
comment.setComment_author_email(email);
comment.setComment_content(content);
ServerRequest request = new ServerRequest();
request.setOperation(Constants.COMMENT);
request.setComment(comment);
Call<ServerResponse> response = requestInterface.cmOperation(request);
response.enqueue(new Callback<ServerResponse>() {
#Override
public void onResponse(Call<ServerResponse> call, Response<ServerResponse> response) {
ServerResponse resp = response.body();
if (resp.getResult().equals(Constants.SUCCESS)) {
sendLoad.setVisibility(View.INVISIBLE);
TastyToast.makeText(context, StringEscapeUtils.unescapeHtml4(resp.getMessage()), TastyToast.LENGTH_LONG,
TastyToast.SUCCESS);
closeCommentDialog();
} else {
sendCommentImage.setVisibility(View.VISIBLE);
sendLoad.setVisibility(View.INVISIBLE);
TastyToast.makeText(context, StringEscapeUtils.unescapeHtml4(resp.getMessage()), TastyToast.LENGTH_LONG,
TastyToast.ERROR);
}
}
#Override
public void onFailure(Call<ServerResponse> call, Throwable t) {
sendLoad.setVisibility(View.INVISIBLE);
sendCommentImage.setVisibility(View.VISIBLE);
TastyToast.makeText(context, "Faild, send Again please", TastyToast.LENGTH_LONG, TastyToast.ERROR);
}
});
}
How can i fix this problem, and send data with UTF8 ?