Skip to content

Formatting your output as JSON

Emil Forslund edited this page Jul 16, 2015 · 11 revisions

Often when you write database applications you will need to send different output to a client app. There are many protocols for sending results over a network. One of the most common is json.

Speedment can handle JSON output out of the box. It is as simple as calling the toJson-method of an entity.

Single entity

// Single user as json.
User user = ...;
String json = user.toJson();

Multiple entities

Using method references, this can be done inline in the stream declaration.

// List of all users as json.
List<String> users = User.stream()
    .map(User::toJson)
    .collect(toList());

If you want to parse the complete result to one single json array, simply call collect.

// Json array of all users.
String json = User.stream().collect(CollectorUtil.toJson());

Choose which data to include

Often you don't want every column to be included in the json output. In the User example above, you might have hashed passwords and other sensitive user information that you don't want to expose. Limiting which columns to expose is easy using the Json-object.

// Only include first- and lastname of users.
JsonFormatter<User> formatter = new JsonFormatter<User>()
    .put(UserField.FIRSTNAME)
    .put(UserField.LASTNAME);
        
String json = User.stream().collect(CollectorUtil.toJson(formatter));

Follow foreign-keys

The formatter can be configured to follow foreign keys. In this example, we also want to include all the images posted by every user in the json output. In the database, each Image has a foreign key to a User. Speedment use this to create a backward stream from User to Image.

// Include a list of image titles for each user.
JsonFormatter<User> formatter = new JsonFormatter<User>()
    .put(UserField.FIRSTNAME)
    .put(UserField.LASTNAME)
    .putAll("images", User::images, new JsonFormatter<Image>()
        .put(ImageField.TITLE)
    );

String json = User.stream().collect(CollectorUtil.toJson(formatter));

Result

[
    {
        "firstname" : "Spire",
        "lastname" : "Harrysson",
        "images" : [
            {"title" : "sunset.jpg"},
            {"title" : "desert.jpg"},
            ...
            {"title" : "forest.jpg"}
        ]
    },
    ...
]

Grab all columns

If you don't want to add every single column in a table to a formatter, you can simply include all in the creation of the formatter object.

// Include all columns in the table 'User'
JsonFormatter<User> formatter = JsonFormatter.allFrom(User.class);

Sometimes you want to use all the columns except for some that might contain sensitive data. In those cases, the .remove() method is handy.

// Include all columns in the table 'User' except for 'password'
JsonFormatter<User> formatter = JsonFormatter
    .allFrom(User.class)
    .remove(UserField.PASSWORD)
;