Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
19
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

Spring MVC+RestTemplateで配列JSONをJavaBeanの配列又はListに変換する

前回は、Jackson単体で「配列JSONをJavaBeanの配列又はListに変換する方法」を紹介しました。今回は、Spring MVCとSpring Webから提供されているRestTemplateで「配列JSONをJavaBeanの配列又はListに変換する方法」を紹介したいと思います。

前回と同様に、以下のようなJSONをJavaBean(Todo)の配列やリストにマッピングします。

  • 配列JSON
[
  {
    "title" : "Jsckson勉強会"
  }
  ,
  {
    "title" : "飲み会"
  }
]
  • JavaBean(Todo)
public class Todo {
    private String title;

    public String getTitle() {
        return title;
    }

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

動作検証バージョン

  • Spring Boot 1.3.6.RELEASE
  • Spring Framework 4.2.7.RELEASE
  • Jackson 2.6.7

検証コード

Spring MVCで配列JSONを読み込む

リクエストBODYに設定された配列JSONを、Spring MVCのHandlerメソッドの引数(JavaBeanのリスト)として受け取り方法をみていきましょう。
Handlerメソッドの引数として受け取り場合は、引数の型をList<T>とし、引数に@org.springframework.web.bind.annotation.RequestBodyするだけで実現できます :smile:


@RequestMapping(path = "/api/v1/todos", method = RequestMethod.POST)
public List<Todo> post(@RequestBody List<Todo> todos) {
    return todos;
}

RestTemplateで配列JSONを読み込む

実際にRestTemplate経由でSpring MVCのHandlerメソッドを呼び出してみます。なお、Junitで作っていますが、今回はAssertは省略させてもらいます。

package com.example;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = JsonDemoApplication.class)
@WebIntegrationTest(randomPort = true)
public class SpringWebMvcJsonArrayTests {

    @Value("http://localhost:${local.server.port}/api/v1/todos")
    private URI uri;

    private final RestTemplate restTemplate = new RestTemplate();

    private final List<Todo> requestTodoList = Arrays.asList(
            new Todo("Jsckson勉強会")
            , new Todo("飲み会")
    );

    /**
     * 配列として読み込む
     */
    @Test
    public void array() throws IOException {

        Todo[] todoArray = restTemplate.postForObject(uri, requestTodoList, Todo[].class);
        for (Todo todo : todoArray) {
            System.out.println(todo.getTitle());
        }

    }

    /**
     * 配列として読み込みArrays#asListでリスト化する
     */
    @Test
    public void arrayConvertListUsingArraysAsList() {

        List<Todo> todoList = Arrays.asList(restTemplate.postForObject(uri, requestTodoList, Todo[].class));
        for (Todo todo : todoList) {
            System.out.println(todo.getTitle());
        }

    }

    /**
     * ParameterizedTypeReferenceを使用してリストとして読み込む
     */
    @Test
    public void listUsingParameterizedTypeReference() {
        RequestEntity<List<Todo>> requestEntity = RequestEntity.post(uri).body(requestTodoList);
        ResponseEntity<List<Todo>> responseEntity = restTemplate.exchange(requestEntity, new ParameterizedTypeReference<List<Todo>>() {});
        for (Todo todo : responseEntity.getBody()) {
            System.out.println(todo.getTitle());
        }
    }

}

配列として読み込む

一番シンプルな読み込み方法です。メソッド内の処理だけで使う+拡張For文などで単純な繰り返し処理を行うだけなら配列でもよいと思います。

Todo[] todoArray = restTemplate.postForObject(uri, requestTodoList, Todo[].class);

配列として読み込みArrays#asListでリスト化する

読み込んだ配列をメソッドの返り値として返却するような場合は、配列ではなくリストを使うのが一般的でしょう。そんな時は、java.util.Arrays#asList(T...)を使うと簡単にリスト化できます。なお、この方法でリスト化すると、リストに対して要素の追加や削除などができないリストが生成されます。(要素を追加、削除するとjava.lang.UnsupportedOperationExceptionが発生します)

List<Todo> todoList = Arrays.asList(restTemplate.postForObject(uri, requestTodoList, Todo[].class));

ParameterizedTypeReferenceを使用してリストとして読み込む

リストとして読み込む方法もあります。リストとして読み込む場合は、読み込みたい型をorg.springframework.core.ParameterizedTypeReferenceの型パラメータに指定します。この方法で生成したリストに対しては、要素の追加や削除もできます。

ResponseEntity<List<Todo>> responseEntity =
    restTemplate.exchange(requestEntity, new ParameterizedTypeReference<List<Todo>>() {});

まとめ

Spring MVCの方はHandlerメソッドの引数にリストを宣言するだけなので非常にGoodです :thumbsup:
RestTemplateの方は、前回紹介した(Jackson単体での実装方法)とほとんど同じですね。やっぱりParameterizedTypeReference(TypeReference)はあまり好きになれないな〜 :sweat_smile:

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
19
Help us understand the problem. What are the problem?