Is there any simple way in Retrofit to convert passed object to JSON automatically?
This is my Retrofit interface :
#FormUrlEncoded
#POST("/places/name")
void getPlacesByName(#Field("name") String name,
#Field("city") String city,
#Field("tags") Tags tags,
Callback<PlaceResponse> callback);
At first I thought that if I pass Tags object it will be automatically converted to JSON , but in reality request looks like this :
name=pubs&city=London&tags=com.app.database.model.Tags%4052aa38a8
Is there any simple way to convert POJO to JSON in Retrofit?
You are creating a URL with parameters because you're using the #URLEncoded and passing the parameters as #Field.
Here is the solution:
#POST("/places/name")
void getPlacesByName(#Body RequestObject req, Callback<PlaceResponse> callback);
Additionaly, I would advise on using #GET for retrieving objects. #POST is used for creating an object and #PUT for updating. Although this isn't wrong, it as recomendation in order be RESTful compliant.
Use Jackson to convert it directly to a String:
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = ow.writeValueAsString(object);
Or use Gson: http://www.mkyong.com/java/how-do-convert-java-object-to-from-json-format-gson-api/
Related
How do I send the following object to server using retrofit 2:
{"list":[
{
"addrress1":
{"addressLine1":"EktaColony",
"addressLine2":"Warje",
"country":"India",
"state":"Maharashtra",
"city":"Pune",
"zipcode":411058},
},
{address2:{.....,.....,...}}
]}
I am using Rxjava.
You can send the json as body of HTTP request. Retrofit provides the annotation #Body for its use
So in your interface
#POST("/yourserver/api")
Observable<ResponseType> sendReq(#Body RequestParser parser);
Your RequestParser Object is the object mapped from the json string. You can use any Json serializer libraries like gson or jackson for it.
Trying to POST something like this with GSON and retrofit:
{user: {"email":"asdfghj#wedssd.jk","name":"fjnhfioewhifhjierj","password":"password""} }
instead of
{"email":"asdfghj#wedssd.jk","name":"fjnhfioewhifhjierj","password":"password"}
TypedInput and TypedByteArray removed in 2.0, how this is possible?
Create class with name User with variables email,name,password.
Create a Class with any name xyz having Object of User.
After that Parse xyz class for Gson with Retrofit.
I'm using retrofit2 to comunicate with a webapi.
I need to set the URL of the webapi dynamically beacuase the user can change it, so i use the #Url annotation to specify it like this:
#POST
Call<LoginResponse> login(#Url String url, #Body LoginRequest user);
In one of the operations, i need to send some path parameters to the server, so i do this:
#GET
Call<DataResponse> getOrder(#Url String url,
#Header(WEBAPI_EMAIL_HEDER) String email,
#Header(WEBAPI_TOKEN_ID_HEDER) String token,
#Path("id") int id);
When i call the operation getOrder(...), an exception is rised by retrofit because i am not suppoused to use #Url and #Path parameters in the same operation.
This is the exception:
java.lang.IllegalArgumentException: #Path parameters may not be used with #Url. (parameter #4)
One solution is to replace the id parameter on the url and use only the #Url parameter in the invokation. But i think this is not the best way, beacuase i will be doing this with all the operations with #Path parameters.
Is there any other cleaner solution? Maybe using another retrofit2 annotation?
Thanks in advance.
As described in the post Retrofit 2 - Dynamic URL, the #Url notation assumes that the String is a fully defined URL and does not check whether it contains #Path variables.
To use the #Path annotation, you have to configure an endpoint URL and include the #Path variable inside the #GET() annotation.
There is a workaround. Incase of a dynamic Url with some variable path, we can define a string format with paths denoted by %s arguments.
E.g:
Suppose the dynamic url with path is : https://www.example.com/users/{id}/whoami
Here we can just replace {id} with %s. So now it becomes,
val formatString = https://www.example.com/users/%s/whoami
Now we can use it as a format string and replace it with required id.
val url = formatString.format(id)
and in the retrofit interface, use #Url parameter in the function.
interface AnyService {
fun whoAmI(#Url url:String): Call<ResponseBody>
}
Incase you are using MVVM architecture, you can call the formatting code in the concerned repository.
I can't get a grasp on Retrofit.. I have an api that returns a result like this: {"user":[{"id":"11","username":"jason95","password":"9355a70301e214efa92b0c5a75be3d29"}]}
This is my interface: http://notepad.cc/retrointerface
This is my code for the callback: http://notepad.cc/retrocallback
If anyone can point me to the correct way to Retrofit, I would GREATLY appreciate it..
By default, Retrofit uses Gson to parse and map the response body from the server to your result object. With the response you're expecting, you need to write a class that maps the JSON object to a Java object. Something like below:
public class ResponseObject {
User[] user;
class User {
String id;
String username;
String password;
}
}
You need to read more about Gson to get that part right. Here's a nice tutorial about using Retrofit with Gson: http://engineering.meetme.com/2014/03/best-practices-for-consuming-apis-on-android/
You could use something other than Gson, but Gson works with Retrofit without any hassle, and will probably fit your needs perfectly.
I am using Retrofit to hit an api. I need to get both Json and header response. So my interface method is like this. So in Response type Object I get response header from response.getHeaders(). But when I try to get the json response from response.getBody(), I don't get a proper response. I need help in fetching and parsing the json response from the Response object :-(
#GET("/api/hello/categories")
retrofit.client.Response getData();
getBody() doesn't return a String directly, you'll have to convert it yourself if you don't want to user Retrofit's built converters.
This link should be a simple way to grab the String from the response, and you can parse it accordingly.