Using PATCH Method In Retrofit and #Body Annotation - android

My Url is
http://sales.xxxxx.com/api/v2/customers/5101117835
When I use this code the response code is always 500.
Interface Code
#Headers({ "Content-Type: application/json;charset=UTF-8"})
#PATCH("customers/{custId}")
Call<GeoTag> postGeoTagData (#Body geoTagUserData geoTag, #Path("custId") String id, #Header("Authorization") String auth);
In Activity
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(" http://sales.erprnd.com/api/v2/")
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiInterface apiInterface = retrofit.create(ApiInterface.class);
Call<GeoTag> geoTagCall = apiInterface.postGeoTagData(geoTagUserData, CustCode, "Bearer "+body.getToken() );
geoTagCall.enqueue(new Callback<GeoTag>() {
#Override
public void onResponse(Call<GeoTag> call, Response<GeoTag> response) {
Toast.makeText(GeoTaggingActivity.this, ""+response.code(), Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<GeoTag> call, Throwable t) {
Toast.makeText(GeoTaggingActivity.this, "Failed", Toast.LENGTH_SHORT).show();
}
});
When I use Postman the response is 201 AND Response IS {} which is ok. My jsonObject is
{
"latitude":11.22,
"longitude":22.11,
"alt_address":"test address",
"height":"12 ft",
"width":"24 ft",
"photo": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMAAAAD"
}
I Have created another class where i get all information from user which is
geoTagUserData i get all the info perfectly
Please Help me find the error .

Finally I got The Solution which is, When I Send Data to Send Data to server from My App it just get the value against every field form geoTagUserData Class it doesn't
#post Converted Data in JSON Format. When My Server Find That I just Values Not In JSON Format
Then It Just Rejected And Return 500 error
So, My solution is just Using Gson Converter get The value form
user and Converted it to JSON object. and Send That to Server Which will Return 201

Related

Not receiving json data with a REST call

I am trying to consume my own REST call using retrofit. My only clue on why it doesn't work is that it says that the type of information is "text/html" even though I am sure it's json. That being said I haven't found any answers that solve my problem.
Payload:
[
{
"user_id": "32",
"username": "Marko",
"last_activity": "2020-04-26 20:44:00",
"user_image": "slika2"
},
{
"user_id": "33",
"username": "dejan",
"last_activity": "2020-04-26 20:44:00",
"user_image": "slika3"
}
]
My chat class:
public class Chat {
#SerializedName("user_id")
private String userId;
private String username;
#SerializedName("last_activity")
private String lastActivity;
#SerializedName("user_image")
private String userImage;\
...constructor/getters
}
Api Interface:
#FormUrlEncoded
#POST("api_get_all_chats.php")
Call<List<Chat>> getChats(
#Field("id") String id
);
Api client:
public static Retrofit getClient() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.level(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
retrofit = new Retrofit.Builder()
.baseUrl("http://MYIP/emob%20projekat/api/")
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
return retrofit;
}
And the whole request:
apiInterface = ApiClient.getClient().create(userApi.class);
Call<List<Chat>> call = apiInterface.getChats(u.getUserInfo().getUserId());
call.enqueue(new Callback<List<Chat>>() {
#Override
public void onResponse(Call<List<Chat>> call, Response<List<Chat>> response) {
chatList = new ArrayList<>(response.body());
chatAdapter = new ChatAdapter(getApplication().getApplicationContext(), R.layout.user_view, chatList);
listView.setAdapter(chatAdapter);
}
#Override
public void onFailure(Call<List<Chat>> call, Throwable t) {
Toast.makeText(getApplication().getApplicationContext(), "ne valja" , Toast.LENGTH_LONG).show();
}
});
Any type of a clue where I am messing up would be much appreciated.
You base url has space when I decoded it I got
http://MYIP/emob projekat/api/
i recommend you to put base URL without encoding
How about cleartextTrafficPermitted="true" on your AndroidManifest. I see you code is fine and I think maybe the problem about your URL with a http scheme.
You can try to specify what response your client expects with Accept:application/json either in you API Interface with:
#FormUrlEncoded
#Headers({"Accept:application/json"})
#POST("api_get_all_chats.php")
Call<List<Chat>> getChats(
#Field("id") String id
);
Either in your API client with new Retrofit.Builder().addHeader("Accept","application/json");.
This issue in square/retrofit is very similar to yours (only the inverse, since in the issue it is the server that does not accepts text/html while in your case it seems to be your client. Maybe, as in the issue, you are employing gson as well which cannot parse the text/html flavored response)
You need an interceptor like this.
public class CustomInterceptor extends Interceptor {
#override
public Response intercept(Interceptor.Chain chain) {
return chain.proceed(chain.request().newBuilder().addHeader("Content-Type", "application/json").addHeader("Accept", "application/json").build())
}
}
First try to log the request, to see exactly what is sent, with headers, url, body and response : https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor
Secondly, are you sure that you have to make a POST request, a GET seems better ?

How to send a JSON POST request using Retrofit in Android, and recieve a String response

I'm using Retrofit2 for the first time and have a few issues.
This is the code snippet used to call the REST API
//building retrofit object
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://192.168.0.71:9000/api/uniapp/")
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
.build();
APIService service = retrofit.create(APIService.class);
//defining the call
Call<String> call = service.refreshAppMetaConfig("0");
//calling the api
call.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
//displaying the message from the response as toast
System.out.println("Uniapp :"+response);
}
#Override
public void onFailure(Call<String> call, Throwable t) {
System.out.println("Uniapp :"+t.getMessage());
}
});
This is the APIService class :
public interface APIService {
//The register call
#FormUrlEncoded
#POST("appmetaconfigjson")
Call<String> refreshAppMetaConfig(#Field("versionId") String versionId);
}
I'm using Play framework for creating the REST API. I am getting an internal server error. The API is not able to read the JSON request. But if I hit the API through Postman, it returns the response. Any suggestions?
Ive added the postman request screenshot.
As I can see from your screenshots of Postman, you're sending JSON body to REST API. When you select body type as raw - application/json in Postman, it automatically includes
Content-Type:application/json
as header. Hence, the request is successful in Postman.
Now, in order to make it work above request successfully in your Android application, you need to set headers with the request you send to REST API.
In APIService interface do the below changes.
import retrofit2.http.Body;
import okhttp3.ResponseBody;
import java.util.Map;
public interface APIService {
//The register call
// #FormUrlEncoded <==== comment or remove this line
#Headers({
"Content-Type:application/json"
})
#POST("appmetaconfigjson")
Call<ResponseBody> refreshAppMetaConfig(#Body Map<String, String> versionId);
}
Remove or comment #FormUrlEncoded annotation as we're sending JSON not FormUrlEncoded data.
Add #Headers() annotation with Content-Type:application/json
Change method parameter to #Body Map<String, String> versionId. The #Body annotation converts (serializes) Map (HashMap) data into JSON body when you request to API.
Change return parameter from String to ResponseBody.
Use the above-modified method as below
// code...
//defining the call
// create parameter with HashMap
Map<String, String> params = new HashMap<>();
params.put("versionId", "0");
Call<ResponseBody> call = service.refreshAppMetaConfig(params);
//calling the api
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//displaying the message from the response as toast
// convert ResponseBody data to String
String data = response.body().string();
System.out.println("Uniapp : " + data);
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
System.out.println("Uniapp : " + t.getMessage());
}
});
Here also you need to change parameter from Call<String> to Call<ResponseBody>. And convert the response inside onResponse() method using response.body().string();.

Retrofit - Get Raw non JSON Array

I am using Retrofit2 for the first time and have a problem to get a simple Array in non JSON format.
Error: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 3 path $[0]
This means its not an JSON Object since it does not start with "{"
I tried adding the ScalarsConverter but it doesent seems to work.
Api: https://chasing-coins.com/api/v1/coins
Interface:
public interface Retro_coins {
#GET("api/v1/coins")
Call<List<Coinlist>> getCoinlist();
}
Class:
public class Coinlist {
private List coinlist;
public List getCoinlist() {
return coinlist;
}
}
Retrofit initialization and call:
String API_BASE_URL = "https://chasing-coins.com/";
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
;
Retrofit retrofit = builder.client(httpClient.build()).build();
Retro_coins client = retrofit.create(Retro_coins.class);
// Fetch list
Call<List<Coinlist>> call =
client.getCoinlist();
// Execute the call asynchronously. Get a positive or negative callback.
call.enqueue(new Callback<List<Coinlist>>() {
#Override
public void onResponse(Call<List<Coinlist>> call, Response<List<Coinlist>> response) {
// The network call was a success and we got a response
Log.w("Yes", response.toString());
}
#Override
public void onFailure(Call<List<Coinlist>> call, Throwable t) {
Log.w("no", t.toString());
}
});
Thanks!
When you are using private List coinlist;, Gson expects the object to be
{
"coinlist":"[]"
}
where as what you are providing is just
["String","String","String"]
furthermore when you use Call<List<Coinlist>> you are expecting the data to be
[
{
"coinlist":"[]"
}
]
Just change your call from Call<List<Coinlist>> to Call<List<String>>. That should fix your problem. Let me know if you need more clarification
Your request Returning String. So you need to Change the Response to String or Need to change your request Call to String.

Capturing List response for a Retrofit Call with Json body

All.
I am trying to use Retrofit to send raw json as a body in a POST Request to the server.
#POST("api/apps")
Call<List<GetApps>> getApp(#Body GetApps body);
I have built the model using jsontopojo for the responses that are coming back.
Inside my call, I have put the constructors and the getters and setters and also toString().
This is my retrofit call.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(APIUrl.BASEURL)
.addConverterFactory(GsonConverterFactory.create())
.build();
APIService apiService = retrofit.create(APIService.class);
Call<List<GetApps>> call = apiService.getApp();
call.enqueue(new Callback<List<GetApps>>() {
#Override
public void onResponse(Call<List<GetApps>> call, Response<List<GetApps>> response) {
List<GetApps> GetApps2 = response.body();
Toast.makeText(getApplicationContext(),"success", Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<List<GetApps>> call, Throwable t) {
Toast.makeText(getApplicationContext(),"Failure", Toast.LENGTH_SHORT).show();
}
});
I am getting an error on this line :
Call<List<GetApps>> call = apiService.getApp();
It says getApp(getApps) cannot be applied to (); Not sure what should go into the ();
You must pass GetApps object as parameter:
GetApps getApps = new GetApps();
//set all your data on getApps
//getApps.setYourData(yourData);
Call<List<GetApps>> call = apiService.getApp(getApps);
You make request
#POST("api/apps")
Call<List<GetApps>> getApp(#Body GetApps body);
which will accept body that will append to URL.
just add body in getApp(#Body GetApps body); // accept JSON string as a parameter.
Happy coding!!
At the top of Post just add #FormEncodedUrl and pass a GetApp model as body ...
Call<List<GetApps>> call = apiservice.getApp(getAppOne);

Get single JSON property value from response JSON using Retrofit 2

I am using Retrofit library (version 2.0.2 as of this writing).
I am making a GET call to a service which responds a big JSON object but I am only interested in one key:value pair in it.
How can I get just that instead of writing a whole new POJO class that matches the JSON response?
Example -
{
status_code: 34,
status_message: "The resource you requested could not be found.",
...,
...
}
I need only status code value (34 here).
Please note, I am just giving an example of this JSON object here. The real one I am dealing with is huge and I care about only one key:value pair in it.
Thanks in advance.
You can refer to the following:
#GET("/files/jsonsample.json")
Call<JsonObject> readJsonFromFileUri();
and
class MyStatus{
int status_code;
}
...
Retrofit retrofit2 = new Retrofit.Builder()
.baseUrl("http://...")
.addConverterFactory(GsonConverterFactory.create())
.build();
WebAPIService apiService = retrofit2.create(WebAPIService.class);
Call<JsonObject> jsonCall = apiService.readJsonFromFileUri();
jsonCall.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
String jsonString = response.body().toString();
Gson gson = new Gson();
MyStatus status = gson.fromJson(jsonString, MyStatus.class);
Log.i(LOG_TAG, String.valueOf(status.status_code));
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
Log.e(LOG_TAG, t.toString());
}
});
...
Debug screenshot

Categories

Resources