Retrofit Android Get Post Example

Retrofit is an open source java library which can be used as web service client API. It can help you construct web service access url,  send the request to web service by numerous HTTP method such as GET, POST, DELETE etc.It can send parameters such as url query string or html form fields value to web server also.

When web service return data to client, it can use data converter to parse out the response data by the data format ( json, xml etc) and return related java object list.

android retrofit process diagram

1. What is Retrofit?

From above picture we can see that Retrofit is used between your code and HTTP web server. It use okhttp to send request and get response from web server internally.

It’s task is to construct the web service url, set request method, add query parameters, add form fields and add headers etc. Then it will use okhttp to send the request to web server and parse the response data to related java object using specified converter.

All the process is maintained by retrofit library, you do not need to care the detail. All you have to do is to tell retrofit which url you want to access, what parameters ( key value pair ) you want to send, what header you want to set and what the returned data parsing converter you want to use.

Retrofit provide a lot of java annotations for you to achieve above tasks. We will introduce them later. Before that let’s look at how to use retrofit in simple sample code.

2. Retrofit Usage Simple Sample Code.

  1. Define a java interface with methods, add retrofit java annotation for each method to let retrofit know which url, HTTP method, parameters etc this method will use. Please note each method must return a retrofit2.Call object in retrofit2, the Call object parameter class type is the response parsed out data class type, if no custom converter is specified, it will parse the response data to a okhttp3.ResponseBody object.
    public interface UserManagerInterface {
    
        /*
         * @FormUrlEncoded : Point out this method will construct a form submit action.
         * @POST : Point out the form submit will use post method, the form action url is the parameter of @POST annotation.
         * @Field("form_field_name") : Indicate the form filed name, the filed value will be assigned to input parameter userNameValue.
         * */
        @FormUrlEncoded
        @POST("user/register.html")
        public Call<ResponseBody> registerUser(@Field("userName") String userNameValue,
                                               @Field("password") String passwordValue,
                                               @Field("email") String emailValue);
    }
  2. Create a retrofit adapter class, set it’s base url ( all method url is relative to this base url. ), add related response data converter factory to it, then get the interface object in step 1.
    Retrofit.Builder retrofitBuilder = new Retrofit.Builder();
    
    retrofitBuilder.baseUrl(baseUrl);
    
    retrofitBuilder.addConverterFactory(converterFactory);
    
    Retrofit retrofit = retrofitBuilder.build();
    
    UserManagerInterface userManagerService = retrofit.create(UserManagerInterface.class);
  3. Create a retrofit2.Callback object and override it’s onResponse and onFailure method. Write logic code in those two method to process server response(Please note the server response data has been parsed by retrofit used converters).
    retrofit2.Callback<UserDTO> callback = new Callback<UserDTO>() {
        @Override
        public void onResponse(Call<UserDTO> call, Response<UserDTO> response) {
            ......
        }
    
        @Override
        public void onFailure(Call<UserDTO> call, Throwable t) {
           ......     
        }
    };
  4. Invoke the created interface object’s method to get a call object and run the call object in asynchronous mode with the callback object just created in step 3.
    Call<UserDTO> call = UserManager.getUserManagerService().getUserByName(userNameValue);
    
    call.enqueue(callback);
  5. Now the retrofit will send request to web server, and when server response, the callback’s onResponse method will be invoked, if web server call failed the onFailure method will be invoked.

3. Retrofit Annotations.

When define method in the java interface, you can use some retrofit annotations to decorate the method. Below is some important annotations that is used in our example.

  1. HTTP Method Annotation : For each HTTP method, there is a annotation in retrofit (GET, POST, HEAD etc). All the annotation is uppercase. The annotation will tell the java interface method which HTTP method will be used to send the request. The parameter in the annotation is the web url that the request will be sent to, it is relative to retrofit base url. The url should not start with /, otherwise retrofit will treat it as relative to root domain.
    // The request url is user/register.html, this relative to base url. 
    @POST("user/register.html")
  2. FormUrlEncoded : This annotation tell retrofit this method will submit html form to web server.
    @FormUrlEncoded
  3. Field : Field annotation tell retrofit this parameter value ( userNameValue ) should be set to a html form field .The field name ( “userName”) is declared in the annotation parameter.
    // Html form filed name is userName, value is userNameValue.
    @Field("userName") String userNameValue
  4. Query : Retrofit will add this annotation data in the url as key value pair query parameter.
    // Will add userName=userNameValue in url as query parameter.
    @Query(“userName”) String userNameValue
  5. For more annotation introduce, please read http://square.github.io/retrofit/#api-declaration

4. Retrofit Converter.

When web server send response data back, retrofit will parse the returned data use user specified data converter. The default converter is okhttp3.ResponseBody if no converter specified.

In this example we use retrofit provided built-in JSON converters which can convert JSON format response data to java objects.

READ :   Android JSON Parsing Use JSONObject / Gson From Url Example

To use Gson converter, you should follow below steps.

  1. Import library com.squareup.retrofit:converter-gson in build.gradle file.
  2. Use below code to create a Gson converter.
    GsonConverterFactory gsonConverterFactory = GsonConverterFactory.create();
  3. Set the JSON converter object to retrofit object.
    retrofitBuilder.addConverterFactory(converterFactory);

5. Retrofit Exmaple.

retrofit android get post example

There are three buttons in this example.

The first button will submit user input data to a web service ( http://www.dev2qa.com/demo/user/register.html ) use POST method. This web service will return a JSON format string. Because we  do not use JSON converter for this process, it will return okhttp3.ResponseBody object ( the default converter) , and we have to parse the response data use Gson in our code.

When you click the second button, it will send a GET request to web service ( http://www.dev2qa.com/demo/user/listUser.html ) . This service will search the user data whose name is Jerry and return a JSON string if found. Because we set Gson converter for this retrofit request, so the response will be parsed out to UserDTO object automatically.

Please Note :  If you want to use Gson converter, you must make sure the java class instance variable field’s name be same with the return JSON text column name accordingly.

For example, if the JSON string is something like below.

{ “userId” : “1”, “userName” : “Jerry”, “password” : “666666”, “email” : “[email protected]” }

The java class should contain below instance variables.

private int userId;

private String userName;

private String password;

private String email;

You can use http://www.jsonschema2pojo.org/ online tool to get your JSON mapped java POJOs.

When you click the third button, it will access another web service ( http://www.dev2qa.com/demo/user/listAllUser.html ) to return all user data and display them in a list view at bottom.

6. Example Source Files.

6.1 Add Below Dependencies In App build.gradle File.

compile 'com.squareup.okhttp3:okhttp:3.10.0'
compile 'com.squareup.retrofit2:retrofit:2.4.0'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.google.code.gson:gson:2.8.2'

 

retrofit android example soure files

6.2 Retrofit Interface Java File.

UserManagerInterface.java

This is the retrofit interface file, it define three methods which will be used to do different tasks. Each method has retrofit annotation to declare what they want retrofit to do.

package com.dev2qa.example.network.retrofit.basic;

import java.util.List;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;

/**
 * Created by Jerry on 3/31/2018.
 */

public interface UserManagerInterface {

    /*
     * @FormUrlEncoded : Point out this method will construct a form submit action.
     * @POST : Point out the form submit will use post method, the form action url is the parameter of @POST annotation.
     * @Field("form_field_name") : Indicate the form filed name, the filed value will be assigned to input parameter userNameValue.
     * */
    @FormUrlEncoded
    @POST("user/register.html")
    public Call<ResponseBody> registerUser(@Field("userName") String userNameValue,
                                           @Field("password") String passwordValue,
                                           @Field("email") String emailValue);


    /*
    *  @GET : Indicate this method will perform a http get action with the specified url.
    *  @Query("userName") : Parse out the userName query parameter in the url and
    *  assign the parsed out value to userNameValue parameter.
    * */
    @GET("user/listUser.html")
    public Call<UserDTO> getUserByName(@Query("userName") String userNameValue);


    /*
    *  Similar with getUserByName method, this method will return all users in a list.
    * */
    @GET("user/listAllUser.html")
    public Call<List<UserDTO>> getUserAllList();
}

6.3 Retrofit Adapter Java File.

This class just has one static method that will return a retrofit interface object. Please note, the base url should be end with “/” in retrofit 2, otherwise it will throw below exception.

baseUrl must end in /.

retrofit base url must end with slash error

UserManager.java

package com.dev2qa.example.network.retrofit.basic;

import retrofit2.Converter;
import retrofit2.Retrofit;

/**
 * Created by Jerry on 3/31/2018.
 */

public class UserManager {

    private static String baseUrl = "http://dev2qa.com/demo/";

    public static UserManagerInterface getUserManagerService(Converter.Factory converterFactory)
    {
        // Create retrofit builder.
        Retrofit.Builder retrofitBuilder = new Retrofit.Builder();

        // Set base url. All the @POST @GET url is relative to this url.
        retrofitBuilder.baseUrl(baseUrl);

        /* The converter factory can be GsonConverterFactory( Convert response text to json object. ),
           if the value is null then convert response text okhttp3.ResponseBody. */
        if(converterFactory != null ) {
            retrofitBuilder.addConverterFactory(converterFactory);
        }

        // Build the retrofit object.
        Retrofit retrofit = retrofitBuilder.build();

        //Create instance for user manager interface and return it.
        UserManagerInterface userManagerService = retrofit.create(UserManagerInterface.class);
        return userManagerService;
    }
}

6.4 Main Activity.

RetrofitGetPostActivity.java

package com.dev2qa.example.network.retrofit.basic;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

import com.dev2qa.example.R;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitGetPostActivity extends AppCompatActivity {

    private static String TAG_RETROFIT_GET_POST = "RETROFIT_GET_POST";

    private EditText userNameEditText = null;

    private EditText passwordEditText = null;

    private EditText emailEditText = null;

    private Button registerButton = null;

    private Button getAllUserButton = null;

    private Button getUserByNameButton = null;

    private ListView userListView = null;

    private ProgressDialog progressDialog = null;

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

        setTitle("dev2qa.com - Android Retrofit Get Post Example.");

        initControls();

        /* When register user account button is clicked. */
        registerButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                showProgressDialog();

                String userNameValue = userNameEditText.getText().toString();

                String passwordValue = passwordEditText.getText().toString();

                String emailValue = emailEditText.getText().toString();

                // Use default converter factory, so parse response body text to okhttp3.ResponseBody object.
                Call<ResponseBody> call = UserManager.getUserManagerService(null).registerUser(userNameValue, passwordValue, emailValue);

                // Create a Callback object, because we do not set JSON converter, so the return object is ResponseBody be default.
                retrofit2.Callback<ResponseBody> callback = new Callback<ResponseBody>(){

                    /* When server response. */
                    @Override
                    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {

                        hideProgressDialog();

                        StringBuffer messageBuffer = new StringBuffer();
                        int statusCode = response.code();
                        if(statusCode == 200)
                        {
                            try {
                                // Get return string.
                                String returnBodyText = response.body().string();

                                // Because return text is a json format string, so we should parse it manually.
                                Gson gson = new Gson();

                                TypeToken<List<RegisterResponse>> typeToken = new TypeToken<List<RegisterResponse>>(){};

                                // Get the response data list from JSON string.
                                List<RegisterResponse> registerResponseList = gson.fromJson(returnBodyText, typeToken.getType());

                                if(registerResponseList!=null && registerResponseList.size() > 0) {

                                    RegisterResponse registerResponse = registerResponseList.get(0);

                                    if (registerResponse.isSuccess()) {
                                        messageBuffer.append(registerResponse.getMessage());
                                    } else {
                                        messageBuffer.append("User register failed.");
                                    }
                                }
                            }catch(IOException ex)
                            {
                                Log.e(TAG_RETROFIT_GET_POST, ex.getMessage());
                            }
                        }else
                        {
                            // If server return error.
                            messageBuffer.append("Server return error code is ");
                            messageBuffer.append(statusCode);
                            messageBuffer.append("\r\n\r\n");
                            messageBuffer.append("Error message is ");
                            messageBuffer.append(response.message());
                        }

                        // Show a Toast message.
                        Toast.makeText(getApplicationContext(), messageBuffer.toString(), Toast.LENGTH_LONG).show();
                    }

                    @Override
                    public void onFailure(Call<ResponseBody> call, Throwable t) {

                        hideProgressDialog();

                        Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_LONG).show();
                    }
                };

                // Use callback object to process web server return data in asynchronous mode.
                call.enqueue(callback);
            }
        });

        /* When get user by name button is clicked. */
        getUserByNameButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                showProgressDialog();

                String userNameValue = userNameEditText.getText().toString();

                // Create Gson converter to convert returned JSON string..
                GsonConverterFactory gsonConverterFactory = GsonConverterFactory.create();

                // Get call object.
                Call<UserDTO> call = UserManager.getUserManagerService(gsonConverterFactory).getUserByName(userNameValue);

                // Create a Callback object.
                retrofit2.Callback<UserDTO> callback = new Callback<UserDTO>() {
                    @Override
                    public void onResponse(Call<UserDTO> call, Response<UserDTO> response) {

                        hideProgressDialog();

                        try {
                            if (response.isSuccessful()) {

                                UserDTO userDto = response.body();

                                List<UserDTO> userDtoList = new ArrayList<UserDTO>();

                                userDtoList.add(userDto);

                                showUserInfoInListView(userDtoList);
                            } else {
                                String errorMessage = response.errorBody().string();
                                Toast.makeText(getApplicationContext(), errorMessage, Toast.LENGTH_LONG).show();
                            }
                        }catch(IOException ex)
                        {
                            Log.e(TAG_RETROFIT_GET_POST, ex.getMessage());
                        }
                    }

                    @Override
                    public void onFailure(Call<UserDTO> call, Throwable t) {
                        hideProgressDialog();
                        Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_LONG).show();
                    }
                };

                // Send request to web server and let callback to process the response.
                call.enqueue(callback);
            }
        });

        /* When click the get all user list button. */
        getAllUserButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showProgressDialog();

                // Create and set Gson converter to parse response JSON string.
                GsonConverterFactory gsonConverterFactory = GsonConverterFactory.create();

                Call<List<UserDTO>> call = UserManager.getUserManagerService(gsonConverterFactory).getUserAllList();

                retrofit2.Callback<List<UserDTO>> callback = new Callback<List<UserDTO>>(){
                    @Override
                    public void onResponse(Call<List<UserDTO>> call, Response<List<UserDTO>> response) {
                        hideProgressDialog();
                        try {
                            if (response.isSuccessful()) {

                                List<UserDTO> userDtoList = response.body();

                                showUserInfoInListView(userDtoList);
                            } else {
                                String errorMessage = response.errorBody().string();
                                Toast.makeText(getApplicationContext(), errorMessage, Toast.LENGTH_LONG).show();
                            }
                        }catch(IOException ex)
                        {
                            Log.e(TAG_RETROFIT_GET_POST, ex.getMessage());
                        }
                    }

                    @Override
                    public void onFailure(Call<List<UserDTO>> call, Throwable t) {
                        hideProgressDialog();
                        Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_LONG).show();
                    }
                };

                // Send request to web server and process response with the callback object.
                call.enqueue(callback);
            }
        });

    }

    /* Display web service returned UserDTO list in a list view at screen bottom. */
    private void showUserInfoInListView(List<UserDTO> userDtoList)
    {
        if(userDtoList != null) {
            ArrayList<Map<String, Object>> itemDataList = new ArrayList<Map<String, Object>>();

            int size = userDtoList.size();

            for(int i=0;i<size;i++)
            {
                UserDTO userDto = userDtoList.get(i);

                Map<String,Object> listItemMap = new HashMap<String,Object>();
                listItemMap.put("userId", "User ID : " + userDto.getUserId() + " , User Name : " + userDto.getUserName());
                listItemMap.put("userData", "Password : " + userDto.getPassword() + " , Email : " + userDto.getEmail());
                itemDataList.add(listItemMap);
            }

            SimpleAdapter simpleAdapter = new SimpleAdapter(this,itemDataList,android.R.layout.simple_list_item_2,
                    new String[]{"userId","userData"},new int[]{android.R.id.text1,android.R.id.text2});

            userListView.setAdapter(simpleAdapter);
        }
    }

    /* Initialize all UI controls. */
    private void initControls()
    {
        if(userNameEditText==null)
        {
            userNameEditText = (EditText)findViewById(R.id.retrofit_user_name);
        }

        if(passwordEditText==null)
        {
            passwordEditText = (EditText)findViewById(R.id.retrofit_password);
        }

        if(emailEditText==null)
        {
            emailEditText = (EditText)findViewById(R.id.retrofit_email);
        }

        if(registerButton == null)
        {
            registerButton = (Button)findViewById(R.id.retrofit_register_button);
        }

        if(getAllUserButton == null)
        {
            getAllUserButton = (Button)findViewById(R.id.retrofit_get_all_user_button);
        }

        if(getUserByNameButton == null)
        {
            getUserByNameButton = (Button)findViewById(R.id.retrofit_get_by_name_button);
        }

        if(userListView == null)
        {
            userListView = (ListView)findViewById(R.id.retrofit_user_list_view);
        }

        if(progressDialog == null) {
            progressDialog = new ProgressDialog(RetrofitGetPostActivity.this);
        }
    }


    /* Show progress dialog. */
    private void showProgressDialog()
    {
        // Set progress dialog display message.
        progressDialog.setMessage("Please Wait");

        // The progress dialog can not be cancelled.
        progressDialog.setCancelable(false);

        // Show it.
        progressDialog.show();
    }

    /* Hide progress dialog. */
    private void hideProgressDialog()
    {
        // Close it.
        progressDialog.hide();
    }
}

6.5 User DTO.

This class is used in get user by name and get all user function.

READ :   Android Swipe Refresh Layout Example

UserDTO.java

package com.dev2qa.example.network.retrofit.basic;

/**
 * Created by Jerry on 3/31/2018.
 */

/* Used by JSON converter to save web server returned JSON string.
   The instance variable name must be same with JSON string column name.
* */
public class UserDTO {

    private int userId;

    private String userName;

    private String password;

    private String email;

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

6.6 RegisterResponse DTO.

In  register user function, we do not set JSON converter, so we get okhttp3.ResponseBody object as response parsed out data. And we use Gson to parse the response body string to below java class object.

RegisterResponse.java

package com.dev2qa.example.network.retrofit.basic;

/**
 * Created by Jerry on 3/31/2018.
 */

public class RegisterResponse {

    private boolean success = false;

    private String message = "";

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

6.7 Android Manifest Xml File.

Because this example need to access internet, so we should declare below permission in android manifest file.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.dev2qa.example">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        
        <activity android:name=".network.retrofit.basic.RetrofitGetPostActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

6.8 Main Activity Layout Xml File.

activity_retrofit_get_post.xml

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="80dp">

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:text="User Name:"
                android:gravity="right"/>
            <EditText
                android:id="@+id/retrofit_user_name"
                android:hint="Input user name."
                android:gravity="left"
                android:text="Jerry"/>

        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:text="Password:"
                android:gravity="right"/>
            <EditText
                android:id="@+id/retrofit_password"
                android:hint="Input password."
                android:gravity="left"
                android:inputType="textPassword"
                android:text="666666"/>

        </TableRow>


        <TableRow
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:text="Email:"
                android:gravity="right"/>
            <EditText
                android:id="@+id/retrofit_email"
                android:hint="Input user email."
                android:gravity="left"
                android:text="[email protected]"/>

        </TableRow>


        <TableRow
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <Button
                android:id="@+id/retrofit_register_button"
                android:text="Register"
                android:layout_span="2"
                android:textAllCaps="false"/>
        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <Button
                android:id="@+id/retrofit_get_by_name_button"
                android:text="Get User By Name"
                android:layout_span="2"
                android:textAllCaps="false"/>
        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <Button
                android:id="@+id/retrofit_get_all_user_button"
                android:text="Get All User List"
                android:layout_span="2"
                android:textAllCaps="false"/>
        </TableRow>

    </TableLayout>

    <ListView
        android:id="@+id/retrofit_user_list_view"
        android:divider="@android:color/holo_green_light"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="10dp"
        android:dividerHeight="3dp"
        android:choiceMode="singleChoice" />
</LinearLayout>
(Visited 7,856 times, 6 visits today)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.