ドキュメント

§JSON の処理と提供

Java では、Play は Jackson JSON ライブラリを使用して、オブジェクトを JSON に変換します。Play のアクションは JsonNode 型を使用し、フレームワークは play.libs.Json API で変換のためのユーティリティメソッドを提供します。

§Java オブジェクトの JSON へのマッピング

Jackson を使用すると、フィールド名、ゲッター、セッターを確認することで、Java オブジェクトを JSON に簡単に変換できます。例として、次の単純な Java オブジェクトを使用します。

// Note: can use getters/setters as well; here we just use public fields directly.
// if using getters/setters, you can keep the fields `protected` or `private`
public static class Person {
  public String firstName;
  public String lastName;
  public int age;
}

オブジェクトの JSON 表現を解析し、新しい Person を作成できます。

Person person = new Person();
person.firstName = "Foo";
person.lastName = "Bar";
person.age = 30;
JsonNode personJson = Json.toJson(person); // {"firstName": "Foo", "lastName": "Bar", "age": 30}

同様に、Person オブジェクトを JsonNode に書き込むことができます。

// parse the JSON as a JsonNode
JsonNode json = Json.parse("{\"firstName\":\"Foo\", \"lastName\":\"Bar\", \"age\":13}");
// read the JsonNode as a Person
Person person = Json.fromJson(json, Person.class);

§JSON リクエストの処理

JSON リクエストは、有効な JSON ペイロードをリクエストボディとして使用する HTTP リクエストです。その Content-Type ヘッダーは、text/json または application/json MIME タイプを指定する必要があります。

デフォルトでは、アクションは **任意のコンテンツ** ボディパーサーを使用します。これを使用して、ボディを JSON(実際には Jackson の JsonNode)として取得できます。

public Result sayHello(Http.Request request) {
  JsonNode json = request.body().asJson();
  if (json == null) {
    return badRequest("Expecting Json data");
  } else {
    String name = json.findPath("name").textValue();
    if (name == null) {
      return badRequest("Missing parameter [name]");
    } else {
      return ok("Hello " + name);
    }
  }
}
public Result sayHello(Http.Request request) {
  Optional<Person> person = request.body().parseJson(Person.class);
  return person.map(p -> ok("Hello, " + p.firstName)).orElse(badRequest("Expecting Json data"));
}

もちろん、独自の BodyParser を指定して、Play にコンテンツボディを JSON として直接解析するように要求する方がはるかに優れており(そして簡単です)。

@BodyParser.Of(BodyParser.Json.class)
public Result sayHello(Http.Request request) {
  JsonNode json = request.body().asJson();
  String name = json.findPath("name").textValue();
  if (name == null) {
    return badRequest("Missing parameter [name]");
  } else {
    return ok("Hello " + name);
  }
}

**注記:** この方法では、Content-type が application/json に設定されている非 JSON リクエストに対して、400 HTTP レスポンスが自動的に返されます。

コマンドラインから **curl** を使用してテストできます。

curl
  --header "Content-type: application/json"
  --request POST
  --data '{"name": "Guillaume"}'
  http://localhost:9000/sayHello

次のように応答します。

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 15

Hello Guillaume

§JSON レスポンスの提供

前の例では JSON リクエストを処理しましたが、text/plain レスポンスで応答しました。有効な JSON HTTP レスポンスを送信するように変更しましょう。

public Result sayHello() {
  ObjectNode result = Json.newObject();
  result.put("exampleField1", "foobar");
  result.put("exampleField2", "Hello world!");
  return ok(result);
}

次のように応答します。

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{"exampleField1":"foobar","exampleField2":"Hello world!"}

Java オブジェクトを返し、Jackson ライブラリによって自動的に JSON にシリアル化することもできます。

public Result getPeople() {
  List<Person> people = personDao.findAll();
  return ok(Json.toJson(people));
}

返す JSON String が既に存在する場合は、そのようにすることもできます。

public Result sayHello() {
  String jsonString = "{\"exampleField1\": \"foobar\"}";
  return ok(jsonString).as(play.mvc.Http.MimeTypes.JSON);
}

§高度な使用方法

アプリケーションの ObjectMapper をカスタマイズするには、2 つの方法があります。

§application.conf での設定

Play は Pekko Jackson シリアル化サポートを使用するため、アプリケーションのニーズに基づいて ObjectMapper を設定できます。jackson-databind 機能のドキュメントでは、MapperSerializationDeserialization 機能を含む、JSON 変換プロセスをさらにカスタマイズする方法について説明しています。

カスタマイズされた ObjectMapper で Play の Json API(toJson/fromJson)を使用する場合は、application.conf にカスタム設定を追加する必要があります。たとえば、Joda 型用の新しいモジュールを追加する場合

pekko.serialization.jackson.play.jackson-modules += "com.fasterxml.jackson.datatype.joda.JodaModule"

または、シリアル化設定を設定する場合

pekko.serialization.jackson.play.serialization-features.WRITE_NUMBERS_AS_STRINGS=true

§ObjectMapper のカスタムバインディング

それでも ObjectMapper の作成を完全に引き継ぎたい場合は、そのバインディング設定をオーバーライドすることで可能です。最初に、application.conf でデフォルトの ObjectMapper モジュールを無効にする必要があります。

play.modules.disabled += "play.core.ObjectMapperModule"

次に、ObjectMapper のプロバイダーを作成できます。

public class JavaJsonCustomObjectMapper implements Provider<ObjectMapper> {

  @Override
  public ObjectMapper get() {
    ObjectMapper mapper =
        new ObjectMapper()
            // enable features and customize the object mapper here ...
            .enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)
            .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

    // Needs to set to Json helper
    Json.setObjectMapper(mapper);

    return mapper;
  }
}

そして、Guice を介して eager singleton としてバインドすることで、ObjectMapperJson ヘルパーに設定されます。

public class JavaJsonCustomObjectMapperModule extends AbstractModule {

  @Override
  protected void configure() {
    bind(ObjectMapper.class).toProvider(JavaJsonCustomObjectMapper.class).asEagerSingleton();
  }
}

その後、モジュールを有効にします。

play.modules.enabled += "path.to.JavaJsonCustomObjectMapperModule"

次へ: XML の操作


このドキュメントに誤りを見つけましたか?このページのソースコードは こちらにあります。ドキュメントガイドライン を読んでから、プルリクエストを自由に送ってください。ご質問やアドバイスがありましたら、コミュニティフォーラム にアクセスして、コミュニティとの会話を開始してください。