Back to Playframework

Handling and serving JSON

documentation/manual/working/javaGuide/main/json/JavaJsonActions.md

3.1.0-M94.8 KB
Original Source
<!--- Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com> -->

Handling and serving JSON

In Java, Play uses the Jackson JSON library to convert objects to and from JSON. Play's actions work with the JsonNode type and the framework provides utility methods for conversion in the play.libs.Json API.

Mapping Java objects to JSON

Jackson allows you to easily convert Java objects to JSON by looking at field names, getters and setters. As an example we'll use the following simple Java object:

@person-class

We can parse the JSON representation of the object and create a new Person:

@to-json

Similarly, we can write the Person object to a JsonNode:

@from-json

Handling a JSON request

A JSON request is an HTTP request using a valid JSON payload as request body. Its Content-Type header must specify the text/json or application/json MIME type.

By default an action uses an any content body parser, which you can use to retrieve the body as JSON (actually as a Jackson JsonNode):

@json-request-as-anycontent

@json-request-as-anyclazz

Of course it’s way better (and simpler) to specify our own BodyParser to ask Play to parse the content body directly as JSON:

@json-request-as-json

Note: This way, a 400 HTTP response will be automatically returned for non JSON requests with Content-type set to application/json.

You can test it with curl from a command line:

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

It replies with:

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

Hello Guillaume

Serving a JSON response

In our previous example we handled a JSON request, but replied with a text/plain response. Let’s change that to send back a valid JSON HTTP response:

@json-response

Now it replies with:

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

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

You can also return a Java object and have it automatically serialized to JSON by the Jackson library:

@json-response-dao

If you already have a JSON String that you'd like to return, you can do that as well:

@json-response-string

Advanced usage

There are two possible ways to customize the ObjectMapper for your application.

Configurations in application.conf

Because Play uses Pekko Jackson serialization support, you can configure the ObjectMapper based on your application needs. The documentation for jackson-databind Features explains how you can further customize JSON conversion process, including Mapper, Serialization and Deserialization features.

If you would like to use Play's Json APIs (toJson/fromJson) with a customized ObjectMapper, you need to add the custom configurations in your application.conf. For example, if you want to add a new module for Joda types

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

Or to add set a serialization configuration:

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

Custom binding for ObjectMapper

If you still want to take completely over the ObjectMapper creation, this is possible by overriding its binding configuration. You first need to disable the default ObjectMapper module in your application.conf

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

Then you can create a provider for your ObjectMapper:

@custom-java-object-mapper

And bind it via Guice as an eager singleton so that the ObjectMapper will be set into the Json helper:

@custom-java-object-mapper2

Afterwards enable the Module:

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