Skip to content

Example

readeyKim edited this page Aug 14, 2019 · 1 revision

기본적인 예제들을 소개합니다.
본 예제는 REST API에 대해 Fake Data를 무료로 제공해주는 JSONPlaceholder을 이용했습니다.


가장 먼저 해야할 일은 HttpClient 객체를 생성하고 Service Interface를 정의하는 것입니다.
예제에서 사용할 base URL은 "http://jsonplaceholder.typicode.com"을 사용했습니다.

HttpClient httpClient = new HttpClient.Builder()
            .baseUrl("http://jsonplaceholder.typicode.com")
            .build();

JSONPlaceholder에서 제공하는 Post data에 대한 json은 다음과 같습니다.
(이 때 POST는 HTTP Method가 아닌, 게시글이란 의미의 영어 단어입니다.)

{
    "userId": 1,
    "id": 1,
    "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}

따라서 이에 맞게 data class를 생성합니다.

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

    public Post(int userId, int id, String title, String body) {
        this.userId = userId;
        this.id = id;
        this.title = title;
        this.body = body;
    }

    // getter and setter 생략

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

그리고 이를 활용하여 Service Interface를 정의합니다.

public interface HttpService {
    @RequestMapping(value="/posts", method=RequestMethod.GET)
    CallTask<List<Post>> getPosts();

    @RequestMapping(value="/posts", method=RequestMethod.POST)
    CallTask<Post> postPosts(@RequestBody Post post);
}

다음 단계로는 HttpClient의 create() 메소드를 통해 Service Interface에 인스턴스를 주입합니다.

HttpService httpService = httpClient.create(HttpService.class);

앞선 준비 작업이 모두 완료되었다면 Http GET method로 Sync/Async 통신을 실습해보겠습니다.

Synchronous GET

    CallTask<List<Post>> posts = httpService.getPosts();
    try {
        Response<List<Post>> res = posts.execute(); // execute()를 실행했을 때 실제 통신이 이루어집니다.
        List<Post> result = res.body();
        for (Post post : result) {
            System.out.println(post.toString());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

Asynchronous GET

    CallTask<List<Post>> posts = httpService.getPosts();
    posts.enqueue(new CallBack() {
        @Override
        public void onResponse(Response<?> response) throws IOException {
            System.out.println(response.body());
        }
        @Override
        public void onFailure(IOException e) {
            System.out.println(e.getMessage());
        }
    });

Synchronous POST

다음은 POST Http Method를 사용한 예제입니다.

    Post newPost = new Post(101, 101, "new Title", "new Body");
    CallTask<Post> post = httpService.postPosts(newPost);
    try {
        Post result = post.execute().body();
        System.out.println(result);
    } catch (IOException e) {
        e.printStackTrace();
    }

이제부터는 HttpService 내 메소드 정의와 HttpClient 객체 생성 단계만 수정해가면서 다양한 예제를 실습해보겠습니다.

@PathParam

@PathParam 을 사용할 때는 Relative URL에 중괄호{} 내 일치하는 name 값이 있어야 합니다.

public interface HttpService {
    @RequestMapping(value="/posts/{id}", method=RequestMethod.GET)
    CallTask<Post> getPostsById(@PathParam("id") int id);
}
    CallTask<Post> post = httpService.getPostsById(5);
    try {
        Post result = post.execute().body();
        System.out.println(result.toString());
    } catch (IOException e) {
        e.printStackTrace();
    }

@Query

    @RequestMapping(value="/posts", method=RequestMethod.GET)
    CallTask<List<Post>> getPostsByUserId(@Query("userId") Integer userId);

@Queries

@Queries 를 사용하면 하나의 name에 대해 여러 개의 value를 query로 구성할 수 있습니다.

    @RequestMapping(value="/posts", method=RequestMethod.GET)
    CallTask<List<Post>> getPostsById(@Queries("id") List<Integer> id);

@QueryMap

@QueryMap 을 사용하면 한 번에 다양한 Query 를 구성할 수 있습니다.

    @RequestMapping(value="/posts", method=RequestMethod.GET)
    CallTask<List<Post>> getPostsByUserId(@QueryMap Map<String, Integer> userId);

@Header, @HeaderMap

@Header, @HeaderMap 를 사용하면 Request에 Header를 설정할 수 있습니다.

    @RequestMapping(value="/posts", method=RequestMethod.GET)
    CallTask<List<Post>> getPostsWithHeader(@Header("content-type") String contentType);
    @RequestMapping(value="/posts", method=RequestMethod.GET)
    CallTask<List<Post>> getPostsWithHeaderMap(@HeaderMap Map<String, String> headerMap);

@Headers

@Headers 는 Parameter 수준이 아닌 Method 수준의 어노테이션입니다.

    @Headers({
        "content-type:text/html",
        "User-Agent:Naver"
    })
    @RequestMapping(value="/posts", method=RequestMethod.GET)
    CallTask<List<Post>> getPostsWithHeaders();

@FormUrlEncoded

@FormUrlEncoded 는 Request Body를 구성하는 하나의 방식으로, @Field@FieldMap 을 사용하여 name:value 형식을 갖습니다.
@RequestBody 와 함께 사용할 수 없습니다.

    @FormUrlEncoded
    @RequestMapping(value="/posts", method=RequestMethod.POST)
    CallTask<Post> postPostsFormUrlEncoded(@Field("userId") int userId, @Field("title") String title);

@DynamicURL

@DynamicURL 은 HttpClient 객체에서 지정한 base URL이나 @RequestMapping 의 relative URL과 상관 없이 동적으로 URL을 설정할 수 있게 해주는 Method 수준의 어노테이션입니다.
@Query, @Queries, @QueryMap 은 사용할 수 있으나 @PathParam 은 사용할 수 없습니다. 실제 URL을 입력 받는 것은 Parameter 수준의 @URL 어노테이션이 설정된 String이나 URL, URI 등을 통해 가능합니다.

    @DynamicURL(method=RequestMethod.GET)
    CallTask<List<Post>> getPostsByDynamicURL(@URL String url);
Clone this wiki locally