How #PUT some value in webservice via Retrofit - android

I wanna send a list of integer with userName and password to WebService some thing like bellow request
UpdateDocumentState(List<int> documentIds, string userName, string password)
But I don't know How to do that ? Use #Post Or #Put ? use #Query Or #Field ? I googled but didn't find any good example or tutorial which explained these well. ( All tutorial I found was about #GET )
could anyone give me some piece of code , how to do that ?

About the use of #PUT or #POST I think you had to get this information from the WebService developers.
Anyway, here sample code for both of Retrofit annotations with or without Callback response.
#POST("your_endpoint")
void postObject(#Body Object object, Callback<Response> callback);
#PUT("/{path}")
String foo(#Path("path") String thePath);
EDIT:
Object is a custom class which represent the data you had to send to the WebService.
public class DataToSend {
public List<Int> myList;
public String username;
public String password;
}
For example when the #POST annotation declaration will be:
#POST
void postList(#Body DataToSend dataToSend, Callback<Response> callback);
and then you call the method using Retrofit service
yourService.postList(myDataToSend, postCallback);

Related

Retrofit pass parameter through post and get result

This is my Api.php
$command=$_POST["command"];
if($command=="getUsers"){
getUsers();
}
elseif ($command=="getNews")
{
getNews();
}
I'm using retrofit to show result in my android app. I need to pass parameter Command through Retrofit Post and Get a result at the same time.
what's the solution?
Try like this example from Retrofit website:
#FormUrlEncoded
#POST("user/edit")
Call<User> updateUser(#Field("first_name") String first, #Field("last_name") String last);
Source: https://square.github.io/retrofit/

How to use two fields in body for methos put in retrofit

I have two strings that I should set them in body for my put request. How can do it with retrofit?
#PUT("/user-management/Account/activate")
#FormUrlEncoded
#Headers({ "Content-Type: application/json"})
Call<Verification> activation(#Part("code") String code , #Part("token") String token);
You may try similar code I posted below: For detailed code please post your context or a part of your code.
#Multipart
#PUT("user/photo")
Call<User> updateUser(#Part("photo") RequestBody photo, #Part("description") RequestBody description);
You can pass multiple Strings in Body like this:
Create a Class
public class Verification
{
public String code;
public String token;
}
Set the data to object
Verification loginCredentials = new Verification();
loginCredentials.code= "12345;
loginCredentials.token= "54321";
Call your api
#PUT("/user-management/Account/activate")
Call<Verification> activation(#Body Verificationcredentials);

Retrofit2 Specify root element and convert datatype

I've just started working with Retrofit2 and the API I'm consuming wraps all valid responses in a "response" object as shown below. I need to tell Retrofit to parse only the values within response without actually nesting them inside another object. For the login code, I'm also faced with the issue of getting a String which I want to convert to an actual time stamp.
This is a sample response from a login request:
{
"status":"success",
"response":{
"token":"test_token",
"expires":"1485217863"
}
}
In the above the only two actual values are:
token
expires
I'm hoping to end up with something like what is shown below.
public class Token {
#SerializedName("token")
String token;
#SerializedName("expires")
Timestamp expires;
public User(String token, String expires ) {
this.token
this.expires = //conversion code omitted.
}
}
You have a couple of options here. You can either use a custom serialiser/deserialiser, type adapters, or you can simply use pojos and unwrap the result yourself.
Let me start with the easiest solution I can think of. Picture you have these classes:
public class ResponseData<T> {
#SerializedName("status")
#Expose
String status;
#SerializedName("response")
#Expose
T response;
public T getResponse() {
return response;
}
// getters and setters and friends
}
public class Token {
#SerializedName("token")
#Expose
String token;
#SerializedName("expires")
#Expose
Timestamp expires;
public Token(String token, String expires) {
this.token = token;
this.expires = expires;
}
}
So one first thing to notice is the use of #Expose. This is a nice to have, but not extremely necessary. It helps you out when you have custom serialisers.
I assumed that you can have multiple api endpoints that return the same kind of body, where the json is:
{
"status":"success",
"response":{
// Can be anything
}
}
And as you can see the response can be anything.
You can then make your retrofit calls return ResponseData<Token> and in your callbacks you can check the value of status and see if you can do getResponse to unpack the result. The advantage of this approach is that you can reuse ResponseData fairly easily.
Another approach is to use custom serialisers or type adapters. This is in my opinion more laborious, but still a valid approach. I think the answer here is quite extensive and explains how you can do this to get the nested object inside response.
To prepare retrofit to use the type adapters, you'll need to inject a configured Gson instance into it. Here's how:
Gson gson = new GsonBuilder()
.registerTypeAdapter(Token.class, new YourTypeAdapter())
.create();
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
// ....
As you can see, we pass the created gson with your type adapter to the GsonConverterFactory used by retrofit. This prepares retrofit to serialise and deserialise Token objects using the given type adapter.
I think the main disadvantage with this approach is that if you want to write a generic deserialiser/serialiser/typeadapter it can become complicated quite fast (assuming you won't have only a Token object).

What is the right way to handle Strings when doing HTTP requests?

I have an Android application acting as a client to my back end server.
I am doing a POST http request with a help of Retrofit lib with a String in the body.
Problem is, Retrofit is most likely escaping double quotes when using GSON builder.
That results in a field in my DB containing double quotes, example: "example_gcm_token".
I need to know whether I should handle that on server side or on client side and how to do that.
I assume it shouldn't be on the server side as it would mean I have to remove escaped quotes for every single endpoint.
#POST ("/Maguss/users/{userId}/gcmtoken")
Call<Void> setGcmToken(#Path("userId") Long userId, #Body StringEntity gcmToken);
I would try to replace the StringEntity with a POJO:
public class SetGcmTokenRequest {
#SerializedName("gcmtoken")
private String gcmToken;
public String getGcmToken() {
return gcmToken;
}
public void setGcmToken(String gcmToken) {
this.gcmToken = gcmToken;
}
}
And change the interface like this:
#POST ("/Maguss/users/{userId}/gcmtoken")
Call<Void> setGcmToken(#Path("userId") Long userId, #Body SetGcmTokenRequest setGcmTokenRequest);

How to send #FormUrlEncoded and #Multipart request at the same time using Retrofit lib

I am writing a client-server Android application. I need to send a file created by user (photo) to server via POST request. The problem is, that when i try to send a file, i can't add a POST Field to my request. Maybe I'm wrong fundamentally, and this operation should be done another way?
#FormUrlEncoded
#Multipart
#POST("/answer/add-file")
Call<AbstractServerResponse> sendSingleFile(#Query("access-token") String accessToken,
#Query("w") String screenWidth,
#Field("answer_id") Integer answerId,
#Part("file") File fileToUpload);
When i try to send files in a multipart way only, i get an exception:
java.lang.IllegalStateException: JSON must start with an array or an object.
As I understand, this happends because the body (main part) of the request is empty.
Multipart requests are used when #Multipart is present on the method. Parts are declared using the #Part annotation.
------ from http://square.github.io/retrofit/
I'm using #Multipart in my project like this:
#POST("/{action}")//POST 多个文件
#Multipart
public void PostAPI(
#Path(value = "action", encode = false) String action,
#Part("path") TypedFile[] typedFiles,
#PartMap Map<String, String> params,
Callback<APIResponse> callback);
Maybe u can try this:
#Multipart
#POST("/answer/add-file")
Call<AbstractServerResponse> sendSingleFile(
#Query("access-token") String accessToken,
#Query("w") String screenWidth,
#Part("answer_id") Integer answerId,
#Part("file") File fileToUpload);
You cannot use both #FormUrlEncoded and #Multipart on a single method. An HTTP request can only have one Content-Type and both of those are content types.

Categories

Resources