I previously implemented the following post request with volley but now i want to use it for retrofit.
So my rest webservice is the following
www.blahblahblah.com/webservice.svc/
I have a function (Person) that is called in the webservice that accepts the following jsonobject
JSONObject jsonObject = new JSONObject();
JSONObject searchCriteria = new JSONObject();
jsonObject.put("FullName", "frank jones");
jsonObject.put("DOB", "06-04-1978");
jsonObject.put("Age", "28");
jsonObject.put("Reason", "Search");
searchCriteria.put("searchCriteria", jsonObject);
So in volley i call www.blahblahblah.com/webservice.svc/Person
and pass the above jsonobject.
Works perfectly
So for Retrofit i've used the same logic, create my jsonobject and pass it in the request
So i use the same url www.blahblahblah.com/webservice.svc/
Create my Post
#POST("Person")
Call<PersonResponseData> getPersonAccess(#Body Object body);
so then my code to get the response
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(urlSearch)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitService service = retrofit.create(RetrofitService.class);
Call<PersonResponseData> personResponseDataCall = service.getPersonAccess(searchCriteria);
personResponseDataCall.enqueue(new Callback<PersonResponseData>() {
#Override
public void onResponse(Response<PersonResponseData> response, Retrofit retrofit) {
int statuscode = response.code();
PersonResponseData personResponseData = response.body();
}
#Override
public void onFailure(Throwable t) {
}
});
I just get a 404 error, any ideas.
As i said this works perfectly in volley but I've done something wrong in retrofit.
Thanks for your help
You can review this question link here is a explanation for use retrofit 2 with POST request
That's only guess, but try following:
1) in Call declaration specify it, not Call getPersonAccess, but Call<PersonResponseData> getPersonAccess;
2) make POJO instead of JSON object and use it as a body instead of passing Object into getPersonAccess call.
Related
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.
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);
I have dynamic JSON, here is example: http://pastebin.com/QMWRZTrD
How I can parse it with Retrofit?
I failed to generate POJO classes, since I have dynamic fields like "5411" and "5412".
EDIT:
I solved it by using Map, since first value is always integer, and second is list of objects.
#FormUrlEncoded
#POST("history.php")
Observable<Map<Integer, List<Vehicle>>> getHistory(#Field("uredjaji") String vehicleId, #Field("startDate") String startDATE, #Field("endDate")
you can use Map to serialize and deserialize it in case of Random keys.
Observable<Map<Integer, List<YourObject>>>
You can get retrofit api call to return String in your RestApi Interface like
Call<String> method(#Path(..)...);
And for that to work you would need to add the scalars converter factory to where you create your Retrofit object.
First you would need to import it:
compile 'com.squareup.retrofit2:converter-scalars:2.1.0'
And then add it:
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("https://your.base.url/")
.build();
And then in onResponse
public void onResponse(Call<String> call, Response<String> response) {
if (response.isSuccessful()) {
Type mapType = new TypeToken<Map<String,List<SomeClass>>() {}.getType(); // define generic type
Map<String,List<SomeClass>> result= gson.fromJson(response.body(), mapType);
} else {
}
}
Also,check out this site it has great tutorials on Retrofit.
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
I need to pass Json in Post request using Retrofit. My Json looks like this:
{
"q": {
"reg": "IND",
"or": [
{
"duration": "12"
}
]
},
"sort": "recent"
}
I created pojo for above Json using jsonschema2pojo which is similar to this: RoomListing.java class
Now I need to make a post request. So I created an API
public interface RoomListingAPI {
#GET("/api/fetch")
void getRoomListing(#Header("x-parse-session-token") String
token, #Body RoomListing list);
}
Created a RestAdapter class
return new RestAdapter.Builder()
.setEndpoint(BASE_URL)
.build();
RoomListingAPI apiservice = restadapter.providesRestAdapter().create(RoomListingAPI.class);
Now I am little bit confused to send Json (Have a look at RoomListing.java) as post request and receive JSON in response ?
Any help would be appreciable.
Firstly, you need to change the annotation from #GET to #POST to do a POST request. Next, assuming you're using Retrofit 1.9.x, you need to do one of two things to get the resulting JSON response, depending on if you want a synchronous or asynchronous response:
Synchronous (on the current thread) - change void to be of the type of the pojo for the response, similar to how you've made your request object (e.g. ResponseType yourMethod(#Body RequestType object);
Asynchronous (on a different thread, with a callback) - add a Callback<ResponseType> to the end of the method, which will then be called on the successful, or unsuccessful, return of the request (e.g. void yourMethod(#Body RequestObject object, Callback<ResponseType> callback);
public interface RoomListingAPI {
#POST("/api/fetch")
void getRoomListing(#Header("x-parse-session-token") String
token, #Field("YOURFIELDNAME") String json);
}
//This method generates your json
private String yourJSON(){
JSONObject jsonRoot = new JSONObject();
JSONObject jsonObject1 = new JSONObject();
JSONArray jsonArray = new JSONArray();
JSONObject jsonObject2 = new JSONObject();
try{
jsonArray.put(jsonObject2);
jsonObject2.put("duration", "12");
jsonObject1.put("reg", "IND");
jsonObject1.put("or", jsonArray);
jsonRoot.put("q", jsonObject1);
jsonRoot.put("sort", "recent");
}catch (JSONException e){
e.printStackTrace();
}
return jsonRoot.toString();
}
RoomListingAPI apiservice = restadapter.providesRestAdapter().create(RoomListingAPI.class);
apiservice.getRoomListing("your_header_token",yourJSON())...
I hope you work but it should be something like this.