Работа с сетью с помощью библиотеки Retrofit2 в Java

Доброго времени суток! В данной статье я расскажу Вам о Java-библиотеке Retrofit2 и о
том, как она упрощает работу с различными сетевыми API (прикладными интерфейсами).
Итак, перейдем сразу к примеру.

Данная библиотека является одной из самых популярных библиотек при разработке Android-приложений.

Пример будет создаваться в среде разработки Intellij IDEA, для этого необходимо
будет создать новый Java проект и через свойства проекта добавить две библиотеки, которые
мы будем использовать далее. Обратите внимание, что для простоты, я не буду останавливаться
на том, как создать проект в среде. Отмечу лишь то, что добавить библиотеки в проект можно,
открыв путь File -> Project Structure -> Project Settings -> Libraries.

Библиотеки, которые нам нужны для проекта:


# сама библиотека 
com.squareup.retrofit2:retrofit:2.1.0

# конвертер формата JSON
com.squareup.retrofit2:converter-gson:2.1.0

После установки библиотек, они появятся в корне проекта в папке lib.. Далее создадим две папки — Java пакета:


# базовый пакет с классом Main
com.example.retrofit2

# будет содержать сервис для работы с API
com.example.retrofit2.network

# будет содержать модели, сгенерированные из JSON ответа сервиса
com.example.retrofit2.network.data

Структура папок проекта:


.
├── lib
│   ├── converter-gson-2.1.0.jar
│   ├── gson-2.7.jar
│   ├── okhttp-3.3.0.jar
│   ├── okio-1.8.0.jar
│   └── retrofit-2.1.0.jar
├── src
│   └── com
│       └── example
│           └── retrofit
│               ├── network
│               │   ├── data
│               │   │   ├── Post.java
│               │   │   └── User.java
│               │   ├── JSONPlaceHolderApi.java
│               │   └── ApiService.java
│               └── Main.java
└── Retrofit2_App.iml

Как будет строиться логика работы приложения? Для примера будем использовать сервис https://jsonplaceholder.typicode.com.
Мы опишем JSON-ответы сервиса с помощью POJO (Plain Old Java Objects) объектов
— простыми Java объектами. Библиотека Retrofit2 будет опрашивать сервис по указанным URL-адресам, конвертировать ответ
в списки Java-объектов, с которыми мы уже будем работать. Итак, код классов далее.

Post.java


package com.example.retrofit.network.data;

public class Post {
    String userId;
    String id;
    String title;
    String body;

    public String getUserId() {
        return userId;
    }

    public Post setUserId(String userId) {
        this.userId = userId;
        return this;
    }

    public String getId() {
        return id;
    }

    public Post setId(String id) {
        this.id = id;
        return this;
    }

    public String getTitle() {
        return title;
    }

    public Post setTitle(String title) {
        this.title = title;
        return this;
    }

    public String getBody() {
        return body;
    }

    public Post setBody(String body) {
        this.body = body;
        return this;
    }

    @Override
    public String toString() {
        return "Post{" +
                "userId='" + userId + ''' +
                ", id='" + id + ''' +
                ", title='" + title + ''' +
                ", body='" + body + ''' +
                '}';
    }
}

User.java


package com.example.retrofit.network.data;

public class User {
    private String id;
    private String name;
    private String username;
    private String email;
    private String phone;
    private String website;

    public String getId() {
        return id;
    }

    public User setId(String id) {
        this.id = id;
        return this;
    }

    public String getUsername() {
        return username;
    }

    public User setUsername(String username) {
        this.username = username;
        return this;
    }

    public String getWebsite() {
        return website;
    }

    public User setWebsite(String website) {
        this.website = website;
        return this;
    }

    public String getName() {
        return name;
    }

    public User setName(String name) {
        this.name = name;
        return this;
    }

    public String getEmail() {
        return email;
    }

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

    public String getPhone() {
        return phone;
    }

    public User setPhone(String phone) {
        this.phone = phone;
        return this;
    }

    @Override
    public String toString() {
        return "User{" +
                "id='" + id + ''' +
                ", name='" + name + ''' +
                ", username='" + username + ''' +
                ", email='" + email + ''' +
                ", phone='" + phone + ''' +
                ", website='" + website + ''' +
                '}';
    }
}

JSONPlaceHolderApi — описание сервиса

Через аннотацию @GET определяется URL-путь для запроса. Список объектов возвращается
в специальной библиотечной обертке — классе Call, посредством которого и будут выполняться запросы —
асинхронные или синхронные.


package com.example.retrofit.network;

import com.example.retrofit.network.data.Post;
import com.example.retrofit.network.data.User;
import retrofit2.Call;
import retrofit2.http.GET;

import java.util.List;

public interface JSONPlaceHolderApi {
    @GET("users")
    Call<List<User>> getUsers();

    @GET("posts")
    Call<List<Post>> getPosts();
}

NetworkService.java — конкретная реализация сервиса


package com.example.retrofit.network;

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

public class ApiService {
    private static ApiService mInstance;
    private static final String BASE_URL = "https://jsonplaceholder.typicode.com";
    private final Retrofit retrofit;

    private ApiService() {
        // создаем объект класса Retrofit
        retrofit = new Retrofit.Builder()
                // устанавливаем базовый URL-адрес
                .baseUrl(BASE_URL)
                // добавляем конвертер
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }

    /**
     * Объект-синглтон - если уже есть экземпляр объекта, то не создаем еще
     * а просто возвращаем
     * 
     * @return
     */
    public static ApiService getInstance() {
        if (mInstance == null) {
            mInstance = new ApiService();
        }
        return mInstance;
    }

    /**
     * Реализация интерфейса сервиса
     * 
     * @return
     */
    public JSONPlaceHolderApi getJSONApi() {
        return retrofit.create(JSONPlaceHolderApi.class);
    }
}

Main.java — сам главный класс


package com.example.retrofit;

import com.example.retrofit.network.ApiService;
import com.example.retrofit.network.JSONPlaceHolderApi;
import com.example.retrofit.network.data.Post;
import com.example.retrofit.network.data.User;
import retrofit2.Response;

import java.io.IOException;
import java.util.List;

public class Main {

    public static void main(String[] args) {

        ApiService service = ApiService.getInstance();
        JSONPlaceHolderApi serviceApi = service.getJSONApi();

        /*
         * синхронные запросы на сервис
         */
        try {
            Response<List<User>> users = serviceApi.getUsers().execute();
            Response<List<Post>> posts = serviceApi.getPosts().execute();

            users.body().forEach(System.out::println);
            posts.body().forEach(System.out::println);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

После запуска данного примера Вы увидите в консоли, преобразованные к строке, представления Java-объектов с актуальными
данными.

Таким образом, мы рассмотрели с Вами основы работы с библиотекой Retrofit2 и запроса данных с помощью аннотации @GET.

Источник