How to use java.time.LocalDate on a Play Framework JSON Rest?

爷,独闯天下 提交于 2019-12-13 16:11:31

问题


I'm trying, without success, to make Play serialize and deserialize java 8 LocalDate.

On Play 2.4, it's said to work out of the box:

Play 2.4 now requires JDK 8. Due to this, Play can, out of the box, provide support for Java 8 data types. For example, Play’s JSON APIs now support Java 8 temporal types including Instance, LocalDateTime and LocalDate.

But I'm unable to make it work.

Here is what I have: I'm using Play 2.4.3, with PlayJava and PlayEbean plugins

Model

@Entity
public class Person extends Model {

    @Id
    public Long id;

    public String name;

    public LocalDate dayOfBirth;

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy")
    public LocalDate anotherDate;

    @Formats.DateTime(pattern = "dd/MM/yyyy")
    public LocalDate andAnotherOne;

    public static Model.Finder<Long, Person> find = new Model.Finder<Long, Person>(Person.class);
}

Controller

public class PersonController extends Controller {

    public Result create() {
        Person person = Json.fromJson(request().body().asJson(), Person.class);

        person.save();

        return ok(Json.toJson(person));
    }

    public Result all() {
        return ok(Json.toJson(Person.find.all()));
    }
}

routes

POST        /person              @controllers.PersonController.create()

GET         /person              @controllers.PersonController.all()

I test it with a chrome app for REST and got error in the three forms:

{"name":"Fred","dayOfBirth":"2015-09-30"}
{"name":"Fred","anotherDate":"30/09/2015"}  
{"name":"Fred","andAnotherOne":"30/09/2015"}

Error

java.lang.RuntimeException:     com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate     value of type [simple type, class java.time.LocalDate] from String value     ('2015-09-30'); no single-String constructor/factory method
 at [Source: N/A; line: -1, column: -1] (through reference chain:     models.Person["dayOfBirth"])

What am I missing?

update: sample app: https://github.com/fredferrao/LocalDateJSONTest


回答1:


I found the problem, Play is injecting a custom ObjectMapper and I think it's not registering Jdk8Module and JSR310Module of jackson.

I opened an issue

The workaround I found is to set your own ObjectMapper on Global.java

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JSR310Module;
import play.Application;
import play.GlobalSettings;
import play.libs.Json;

/**
 * Criado por ferrao em 01/10/2015.
 */
public class Global extends GlobalSettings {
    public void onStart(Application app) {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new Jdk8Module());
        mapper.registerModule(new JSR310Module());
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        Json.setObjectMapper(mapper);
    }
}

The mapper.configure part I copied from play.libs.Json source



来源:https://stackoverflow.com/questions/32872474/how-to-use-java-time-localdate-on-a-play-framework-json-rest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!