Retrofit POST raw string body - android

I am using Retrofit to send a POST request to a server. The body of the POST must be in the form jdata={"key1":"value1",...} along with a Content-Type header set to application/x-www-form-urlencoded. I found a similar question but the accepted answer is not working.
Here's what I tried -
My interface
public interface APIHandler {
#Headers("Content-Type: application/x-www-form-urlencoded")
#FormUrlEncoded
#POST(URL)
Call<ResponseBody> getdata(#Field("jdata") String jdata);
}
Call function
public void load() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("BASE_URL")
.addConverterFactory(GsonConverterFactory.create())
.build();
// prepare call in Retrofit 2.0
APIHandler iAPI = retrofit.create(APIHandler.class);
String requestBody = "{\"id\":\"value\",\"id1\":\"value2\"}"
Call<ResponseBody> call = iAPI.getData(requestBody);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> c, Response<ResponseBody> response) {
if (response.isSuccess()) {
ResponseBody result = response.body();
String gs = new Gson().toJson(result);
Log.d("MainActivity", "response = " + gs + " status: " + statusCode);
} else {
Log.w("myApp", "Failed");
}
}
#Override
public void onFailure(Call<ResponseBody> c, Throwable t) {
}
});
}
But I receive response = null and status = 200. What am I doing wrong? The expected response is only a string and not a JSON array.

I am leaving this here so that it helps someone.
The above code is correct. As I mentioned in the last line, a plain string response was expected. But since it is not a JSON response, the conversion probably did not work and the response was null. The only solution I could find was to directly convert the response to string -
try {
stresp = response.body().string()
Log.d("MainActivity", "response = " + stresp + " status: " + statusCode);
} catch (IOException e) {
//Handle exception
}
There might be a better way to handle this but that worked for me!

You can use like that. I have tested this and it working fine
public interface APIHandler {
#POST(URL)
Call<ResponseBody> getdata(#Body JsonObject body);
}
Request body:
JsonObject requestBody = new JsonObject();
requestBody.addProperty("id", "value1");
requestBody.addProperty("id1", "value2");
Prepare call in Retrofit 2.0
APIHandler iAPI = retrofit.create(APIHandler.class);
And Call function :
Call<ResponseBody> call = iAPI.getData(requestBody);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> c, Response<ResponseBody> response) {
if (response.isSuccess()) {
String result = response.body().string();
Log.d("MainActivity", "response = " + result);
} else {
Log.w("myApp", "Failed");
}
}
#Override
public void onFailure(Call<ResponseBody> c, Throwable t) {
}
});

Related

Retrofit2 returns 999 when I called api

I use Retrofit2 to call api, when I do apiTest("http://xxx.xx.xx.xxx:xxxx/", "T001", "Futek10911-01"), the response.code is 999 but it returns correct value in Postman. Where's the problem?
private void apiTest(String url, String machId, String check) throws JSONException {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
MyAPIService myAPIService = retrofit.create(MyAPIService.class);
JSONObject jsonObject = new JSONObject();
jsonObject.put("MACHID", machId);
jsonObject.put("CHECK", check);
Call<GetHostTime> call = myAPIService.getHostTime("sRequest", jsonObject);
call.enqueue(new Callback<GetHostTime>() {
#Override
public void onResponse(Call<GetHostTime> call, Response<GetHostTime> response) {
if(response.isSuccessful()){
Log.d("response ", "isSuccessful");
}else {
Log.d("response code ", response.code() + "");
}
}
#Override
public void onFailure(Call<GetHostTime> call, Throwable t) {
Log.d("Failure", t.getMessage());
}
});
public interface MyAPIService {
#POST("TcLeaseParkAPI/api/ParkingAPI/GetHostTime")
#FormUrlEncoded
Call<GetHostTime> getHostTime(#Field("MACHID") String key, #Field("CHECK") JSONObject jsonObject);
}
Comparing your Postman request and your code. It is clear I feel you are sending the request in wrong manner.
So we modify your Retrofit request as follows
public interface MyAPIService {
#POST("TcLeaseParkAPI/api/ParkingAPI/GetHostTime")
#FormUrlEncoded
Call<GetHostTime> getHostTime(#Field("sRequest") JSONObject jsonObject);
And then your request Call as follows
Call<GetHostTime> call = myAPIService.getHostTime(jsonObject);
Now your JSONObject will go in the key sRequest

how to post raw json array to server in retrofit

every time i run this function onfaliure calls
json array
{"ORDER":[{"ORDER_DATE":"2020-09-08 01:28:11 PM","CUSTOMER_ID":"umersaleem_03334033313","PRODUCT_ID":"","QUANTITY":1,"DEAL_ID":"1","ORDER_TOTAL":"600.0"}
interface
#POST("/restaro/index.php/Home/insert_order_info")
Call<CheckloginModel> insertOrder(#Body JSONObject j);
function
retrofitApiInterface.insertOrder(orders)
.enqueue(new Callback<CheckloginModel>() {
#Override
public void onResponse(Call<CheckloginModel> call, Response<CheckloginModel> response) {
if (response.isSuccessful()) {
}
#Override
public void onFailure(Call<CheckloginModel> call, Throwable t) {
Toast.makeText(getApplicationContext(), "Poor internet connection or device is Off ", Toast.LENGTH_SHORT).show();
}
});
}
api response
this the response when the data is inserted through postman
{
"status": 1,
"message": "new order added "
}
when i send it on postman the data is inserting need help thanks in advance
#Headers("Content-Type: application/json")
#POST("/restaro/index.php/Home/insert_order_info")
Call< CheckloginModel> insertOrder(#Body RequestBody body);
request body send with your json and send this request body to api.
JSONObject jsonObject=new JSONObject();
try {
jsonObject.put("value", "value");
} catch (JSONException e) {
e.printStackTrace();
}
RequestBody requestBody=RequestBody.create(MediaType.parse("application/json; charset=utf-8"),jsonObject.toString());
I will only this line and pass requestbody Retrofit call and works for me
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonObject1.toString());
Call<CheckOutResponse> call = RetrofitClient.getInstance().getApi().postOrder(requestBody);
call.enqueue(new Callback<CheckOutResponse>() {
#Override
public void onResponse(Call<CheckOutResponse> call, Response<CheckOutResponse> response) {
CheckOutResponse checkOutResponse = response.body();
#Override
public void onFailure(Call<CheckOutResponse> call, Throwable t) {
}
});
Webservice class
#POST("yourAPiCall")
Call<CheckOutResponse> postOrder(#Body RequestBody requestBody);

HTTP Request not Working with Retrofit but it's work fine in Postman

I am facing a weird problem .. I am in middle of developing application and all my requests works fine but the last three didn't work with no reason !!
I searched for what could cause this problem but i didn't understand anything ... although the request just works fine in Postman !!
here is my request function :
#FormUrlEncoded
#POST("addContractBenefit")
Call<ResponseBody> addContractBenefit( #Header("Accept") String Accept,
#Header("Authorization") String token,
#Field ("contract_id") int contract_id ,
#Field ("contract_benefit") String contract_benefit
);
and here is my requset call :
Call<ResponseBody> responseBodyCall = service.addContractBenefit("application/json","Bearer "+prefManager.getAPIToken() , contract_id , b.contractBenefit.getText().toString() );
responseBodyCall.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
mDialog.dismiss();
String jsonStr = null;
try {
jsonStr = response.body().string();
Log.d("response" , jsonStr);
} catch (IOException e) {
e.printStackTrace();
}
JSONObject json = null;
try {
json = new JSONObject(jsonStr);
JSONObject statesResponses = json.optJSONObject("states");
boolean success = statesResponses.getBoolean("success");
if(success){
Toast.makeText(getContext(), getString(R.string.added_successefuly), Toast.LENGTH_LONG).show();
benefitAdapter.notifyDataSetInvalidated();
b.contractBenefits.invalidateViews();
}
}
catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d("failure", t.getMessage());
mDialog.dismiss();
}});
and RetrofitClientInstance
public static Retrofit getRetrofitInstance() {
if (retrofit == null) {
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
all of my other requests is working fine but i don't know what causing error in these request !!
It was server error it takes another Character set/Collection which is make it not work with retrofit but work on postman

Implementing custom header for retrofit and i get No Retrofit annotation found, error

this below code is calling webservice which i want to implementing that with Retrofit on Android, but i get this error:
No Retrofit annotation found
calling Web Service with CURL:
curl -H "X-Auth-Token: 9HqLlyZOugoStsXCUfD_0YdwnNnunAJF8V47U3QHXSq" \
-H "X-User-Id: aobEdbYhXfu5hkeqG" \
http://localhost:3000/api/v1/channels.list
i wrote this interface like with above code:
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Header;
public interface RocketRestfulService {
#GET("/api/v1/channels.list")
Call<List<ChannelsList>> getChannelsList(
#Header("X-Auth-Token") String AuthToken,
#Header("X-User-Id") String UserId,
ChannelsList channelsList);
}
and i'm calling this rest Web Service by this code:
ChannelsList channelsList = new ChannelsList();
Call<List<ChannelsList>> call = rocketRestfulService.getChannelsList(
"HNv1VtMiyUky2RkXWUydyj4f2bfciQ6DzVQgKULSwfe",
"Wz9ex2N2z9zzJWdzD",
channelsList);
call.enqueue(new Callback<List<ChannelsList>>() {
#Override
public void onResponse(Call<List<ChannelsList>> call, final Response<List<ChannelsList>> response) {
Log.e("contentLength ", response.code() + "");
}
#Override
public void onFailure(Call<List<ChannelsList>> call, Throwable t) {
t.printStackTrace();
}
});
whats problem of my code that i can't call and i get error?
You forgot #Body annotation. And since you have to send a body, you must create a POST to your API. If is not a POST, you must find how to send ChannelsList in order to be a GET request because is depending your server implementation.
#POST("/api/v1/channels.list")
Call<List<ChannelsList>> getChannelsList(
#Header("X-Auth-Token") String AuthToken,
#Header("X-User-Id") String UserId,
#Body ChannelsList channelsList);
problem solved by this below code:
interface:
public interface RocketRestfulService {
#GET("/api/v1/channels.list")
Call<ResponseBody> getChannelsList(
#Header("X-Auth-Token") String AuthToken,
#Header("X-User-Id") String UserId);
}
call request and get response:
ChannelsList channelsList = new ChannelsList();
Call<ResponseBody> call = rocketRestfulService.getChannelsList(
"HNv1VtMiyUky2RkXWUydyj4f2bfciQ6DzVQgKULSwfe",
"Wz9ex2N2z9zzJWdzD");
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, final Response<ResponseBody> response) {
if (response.isSuccessful()) {
try {
String jsonString = response.body().string();
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray jsonarray = jsonObject.getJSONArray("channels");
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e("Err: ", t.getMessage());
}
});

How to convert the json object response from retrofit success response?

I have worked with retrofit file upload. Here by using system.out.println I can track the response body. But can't convert the response to JSON object.
I hereby write my code. Kindly please let me know how do I parse and get the string value using retrofit success message and failure message.
ApiConfig:
public interface ApiConfig {
#Multipart
#POST("general/Candidate/fileUpload")
Call<ResponseBody> upload(
#Header("Authorization") String authorization,
#PartMap Map<String, RequestBody> map,
#Part("id") RequestBody id,
#Part("fileCount") RequestBody fileCount,
#Part("fileType") RequestBody fileType,
#Part("platform") RequestBody platform,
#Part("externalID") RequestBody externalID);
}
ServiceGenerator:
public class ServiceGenerator {
public static final String API_BASE_URL = "http://104.239.173.64/peoplecaddie-api/";
private static Retrofit retrofit = null;
private static OkHttpClient httpClient = new OkHttpClient.Builder()
.readTimeout(60, TimeUnit.SECONDS)
.connectTimeout(60, TimeUnit.SECONDS)
.build();
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create(new Gson()));
public static <S> S createService(Class<S> serviceClass) {
Retrofit retrofit = builder.client(httpClient).build();
return retrofit.create(serviceClass);
}
}
uploadFile1:
private void uploadFile1(Uri fileUri) {
progressDialog.show();
ApiConfig service =
ServiceGenerator.createService(ApiConfig.class);
File file = FileUtils.getFile(this, fileUri);
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
Map<String, RequestBody> map = new HashMap<>();
map.put("fileContent0\"; filename=\"" + file.getName() + "\"", requestFile);
MultipartBody.Part body =
MultipartBody.Part.createFormData("fileContent0", file.getName(), requestFile);
String idStr = "1743";
String fileCountStr = "1";
String fileTypeStr = "SAMPLE";
String platformStr = "Android";
String externalIDStr = "portpolio";
RequestBody idReq =
RequestBody.create(
MediaType.parse("multipart/form-data"), idStr);
RequestBody fileCountReq =
RequestBody.create(
MediaType.parse("multipart/form-data"), fileCountStr);
RequestBody fileTypeReq =
RequestBody.create(
MediaType.parse("multipart/form-data"), fileTypeStr);
RequestBody platformReq =
RequestBody.create(
MediaType.parse("multipart/form-data"), platformStr);
RequestBody externalIDReq =
RequestBody.create(
MediaType.parse("multipart/form-data"), externalIDStr);
// finally, execute the request
Call<ResponseBody> call = service.upload("817b6ce98fd759e7f148b948246df6c1", map, idReq, fileCountReq, fileTypeReq, platformReq, externalIDReq);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call,
Response<ResponseBody> response) {
try {
System.out.println("Rrespppppp--->"+response.body().string());
Log.e("response", "response------------------>" + response.body().string());
JSONObject profileFileUploadResponse = new JSONObject(String.valueOf(response.body()));
Log.e("retro", "retroFileResp------------------>" + profileFileUploadResponse);
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e("Upload error:", t.getMessage());
}
});
}
Here upload file method I can track the response using. This works fine.
System.out.println("Rrespppppp--->"+response.body().string());
But while try to convert the JSON Object it will not work the error code is below. And please let me know how do i parse and get the success and failure response value using this code.
Log.e("response", "response------------------>" + response.body().string());
JSONObject profileFileUploadResponse = new JSONObject(String.valueOf(response.body()));
Log.e("retro", "retroFileResp------------------>" + profileFileUploadResponse);
Thanks in Advance.
**You have to use Gson to get JsonObject response like below.**
public interface getProfileInfo {
#GET("users/{userid}")
Call<JsonObject> getProfileData(#Path("userid") String userId);
}
private void getUserProfileInfo(String userId)
{
getProfileInfo postService=RetrofitApi.makeNetworkRequest().create(getProfileInfo.class);
Call<JsonObject> call = postService.getProfileData(userId);
call.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
System.out.println("user Info :" + response.body().getAsJsonObject());
setUserData(response.body().getAsJsonObject());
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
// Log error here since request failed
System.out.println("Error :" + t.getMessage());
}
});
}
Modified your code. Please try. You will get json object in result
Call<ResponseBody> call = service.upload("817b6ce98fd759e7f148b948246df6c1", map, idReq, fileCountReq, fileTypeReq, platformReq, externalIDReq);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call,
Response<ResponseBody> response) {
try {
System.out.println("Rrespppppp--->"+response.body().string());
Log.e("response", "response------------------>" + response.body().string());
//JSONObject profileFileUploadResponse = new JSONObject(String.valueOf(response.body()));
ResponseBody result = response.body();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e("Upload error:", t.getMessage());
}
});
Retrofit Response is already in json format you can get item by
{ "result": [{ "fileId": 852, "status": 1, "pcData": { "id": 635, "filename": "IMG_20161122_175344.jpg", "filepath": "uploads\/peoplecaddie\/files\/1743_1480742360_IMG_20161122_‌​175344.jpg" } }] }
String fileid=response.body().getresult(0).getFileId();
String status=response.body().getresult(0).getStatus();
You can only call response.body().string() once. From the ResponseBody docs --
The response body can be consumed only once.
You try to consume the body on both of the following two lines
Log.e("response", "response------------------>" + response.body().string());
JSONObject profileFileUploadResponse = new JSONObject(String.valueOf(response.body()));
You can read it once into a variable and reuse that --
final String body = response.body().string();
Log.e("response", "response------------------>" + body);
JSONObject profileFileUploadResponse = new JSONObject(body);
That should fix your problem, but if you don't want to go further and don't want to deal with creating the JSONObject yourself, one of the benefits of retrofit it does deserialization as well. You are already configuring a gson converter to your retrofit, so you should be able to update your call to --
#Multipart
#POST("general/Candidate/fileUpload")
Call<ReturnObject> upload(...)
where ReturnObject is the POJO you want to deserialize to. You will have to update your response handler as well, to expect a ReturnObject type.
Try this, It will work
Change Call Type as JsonElement
#GET("LoginAPI")
Call<JsonElement> getLogin(#Query("Username") String userName,
#Query("Password") String password);
Get Json object from the response
public void onResponse(Call<JsonElement> call, Response<JsonElement> response) {
try {
JSONObject object = new JSONObject(response.body().toString());
textView.setText(object.toString());
} catch (JSONException e) {
e.printStackTrace();
textView.setText(e.getMessage());
}
}

Categories

Resources