1

This is my first time using retrofit and I am getting lost in the instructions. I read the official guides and quite a few other answers and tutorials but I am still having trouble. It seems like they all cover complex scenarios but not just the simple post for one field.

This is the details of what I am trying to do. Post a name to a php server:

Type: application/x-www-form-urlencoded Payload name: e.g. name=John%20Smith

I have spent quite a bit of time and have the basic but I think I am missing somthing:

I have worked out that I need an interface like this:

public interface ApiService {

    @FormUrlEncoded
    @POST("./")
    Call<User> updateUser(@Field("Name") String name);
}

Then i have a model for my user:

public class User {
    @SerializedName("Name")
    String name;
}

Then I have my retrofit client:

public class RetroClient {

private static final String ROOT_URL = "http://alarm.abc.ch/";
public static ApiService RETROFIT_CLIENT;

    public static ApiService getInstance() {
        //if REST_CLIENT is null then set-up again.
        if (RETROFIT_CLIENT == null) {
            setupRestClient();
        }
        return RETROFIT_CLIENT;
    }

    private static void setupRestClient() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(ROOT_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        RETROFIT_CLIENT = retrofit.create(ApiService.class);
    }
}

and I call it like this in the post function in my main activity:

 public void post (){
        mRetrofitCommonService = RetroClient.getInstance();

        call = mRetrofitCommonService.updateUser("test");
        call.enqueue(new Callback<User>() {
            @Override
            public void onResponse(Call<User> call, Response<User> response) {

                System.out.println("responseee  " + response);
            }

            @Override
            public void onFailure(Call<User> call, Throwable t) {
                System.out.println("eeee " + t);
            }
        });

And it is from there that I am totally lost. I am sure it is something small I am missing but not sure what.

Thanks in advance for your help.

EDIT: The code has been changed to reflect my current attempt. This is giving me the following error:

MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 2 path 
Nicholas Muir
  • 2,897
  • 8
  • 39
  • 89

3 Answers3

2

You are almost there! Now you have to call your api.

Sample code

public class App {

    private ApiService apiService = RetroClient.getApiservice();

    public static void main(String[] args) {

        User user = new User("username")
        Call<User> call = apiService.updateUser(user);
        call.enqueue(new Callback<User>() {
            @Override
            public void onResponse(Call<User> call, Response<User> response) {
                int statusCode = response.code();
                User user = response.body();
                // process success
            }

            @Override
            public void onFailure(Call<User> call, Throwable t) {
                // process failure
            }
        });

    }

}

Update with post() method from main activity

public void post() {

    Call<User> call = apiService.updateUser("username");
    call.enqueue(new Callback<User>() {
        @Override
        public void onResponse(Call<User> call, Response<User> response) {
            int statusCode = response.code();
            User user = response.body();
        }

        @Override
        public void onFailure(Call<User> call, Throwable t) {
            // Log error here since request failed
        }
    });

}
Issam El-atif
  • 2,366
  • 2
  • 17
  • 22
2

See my onCreate method how i did it.

public class LoginActivity extends AppCompatActivity {

    RetrofitCommonService mRetrofitCommonService;
    Call<LoginResponse> call;
    String firstName, lastName, userId, token;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        mRetrofitCommonService = RetrofitClient.getInstance();

        call = mRetrofitCommonService.doLogin("danish.sharma@gmail.com", "12345678");
        call.enqueue(new Callback<LoginResponse>() {
            @Override
            public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
                LoginData responseReg = response.body().getData();

                firstName = responseReg.getFirstName();
                lastName = responseReg.getLastName();
                userId = responseReg.getUserId();
                token = responseReg.getToken();

                System.out.println("responseee  " + firstName + " " + lastName);
            }

            @Override
            public void onFailure(Call<LoginResponse> call, Throwable t) {
                System.out.println("eeee " + t);
            }
        });
    }
}

My RetrofitClient class:

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by Danish.sharma on 7/22/2016.
 */
public class RetrofitClient {
    public static final String BASE_URL = "http://face2friend.com/";
    public static RetrofitCommonService RETROFIT_CLIENT;


    public static RetrofitCommonService getInstance() {
        //if REST_CLIENT is null then set-up again.
        if (RETROFIT_CLIENT == null) {
            setupRestClient();
        }
        return RETROFIT_CLIENT;
    }

    private static void setupRestClient() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        RETROFIT_CLIENT = retrofit.create(RetrofitCommonService.class);
    }
}

& RetrofitCommonService class:

import com.aquasoft.retrofitexample.model.LoginResponse;
import com.aquasoft.retrofitexample.model.RegistrationResponse;
import com.aquasoft.retrofitexample.model.UserImageResponse;
import com.aquasoft.retrofitexample.model.VehicleResponse;

import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;

/**
 * Created by Danish.sharma on 7/22/2016.
 */
public interface RetrofitCommonService {

    /*@POST("http://server.pogogamessupport.com/parkway/api/v1/registration")
    Call<RegistrationResponse> createUser(@Body RegistrationResponse user);*/

    @FormUrlEncoded
    @POST("registration")
    Call<RegistrationResponse> doRegistration(@Field("email") String email, @Field("firstname") String firstname, @Field("lastname")
    String lastname, @Field("password") String password);

    @FormUrlEncoded
    @POST("login")
    Call<LoginResponse> doLogin(@Field("email") String email, @Field("password") String password);

    @FormUrlEncoded
    @POST("listvehicle")
    Call<VehicleResponse> getAllVehicle(@Field("userId") String userId, @Field("token") String token);

    @Multipart
    @POST("updateprofilepic")
    Call<UserImageResponse> updateUserImage(@Part("userId") RequestBody userId, @Part("token") RequestBody  token, @Part MultipartBody.Part image);

}

& last thing about dependencies in build.gradle which i'm using:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.google.code.gson:gson:2.6.2'
    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    compile 'com.squareup.okhttp:okhttp:2.4.0'
    provided 'org.glassfish:javax.annotation:10.0-b28'
}

Do comment if you still need any help.

Däñish Shärmà
  • 2,891
  • 2
  • 25
  • 43
1

On the object returned from getApiService() you will be able to call updateUser().

In response to this call you will then receive a Call object like the following:

Call<User> userUpdateCall = RetroClient.getApiService().updateUser(somestring);

Then to execute this call synchronously do the following:

userUpdateCall.execute();

UPDATE

Sorry I missed it before. In your ApiService interface, do something like the following:

@FormUrlEncoded
@POST("YourPostEndpoint")
Call<User> updateUser(@Field("Name") String name);

ASYNC CALL

For more details see here

To call it asynchronously, instead of .execute() use the following (code taken from above link and modified to this scenario:

userUpdateCall.enqueue(new Callback<User>() {  
    @Override
    public void onResponse(Call<User> call, Response<User> response) {
        if (response.isSuccessful()) {
            // user available
        } else {
            // error response, no access to resource?
        }
    }

    @Override
    public void onFailure(Call<List<Task>> call, Throwable t) {
        Log.d("Error", t.getMessage());
    }
}
StuStirling
  • 15,601
  • 23
  • 93
  • 150
  • thanks for your response. In my main activity i made a function called post and I put in the code you wrote. I got error: java.lang.IllegalArgumentException: Missing either POST URL or Url parameter. – Nicholas Muir Nov 17 '16 at 11:25
  • Thanks I was able to put "./" as my end point and that fixes that error. But then it gave me an error that I am running it on the ui thread? I thought this was ansychronus. – Nicholas Muir Nov 17 '16 at 11:37
  • See above for the asynchronous functionality. FYI, the link I attached is also very good for all things retrofit 2 – StuStirling Nov 17 '16 at 12:06
  • Looking over that code, where do you sett the Name string? – Nicholas Muir Nov 17 '16 at 12:12
  • Wherever you want. That's your variable to input. You can see in my first line of code I posted I just put `somestring` – StuStirling Nov 17 '16 at 12:24
  • Hey I worked it out with the help from one of the other people. But thanks heaps for helping me out! – Nicholas Muir Nov 17 '16 at 12:44