如何在 Play Framework JSON Rest 上使用 java.time.LocalDate?

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

我正在尝试使 Play 序列化和反序列化 java 8 LocalDate。

在 Play 2.4 上,据说开箱即用:

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.

但我无法让它工作。

这是我的资料: 我正在使用带有 PlayJava 和 PlayEbean 插件的 Play 2.4.3

型号

@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);
}

控制器

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()));
    }
}

路线

POST        /person              @controllers.PersonController.create()

GET         /person              @controllers.PersonController.all()

我使用 chrome REST 应用对其进行了测试,并在三种形式中出现错误:

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

错误

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"])

我错过了什么?

更新: 示例应用程序:https://github.com/fredferrao/LocalDateJSONTest

我发现了问题,Play 正在注入一个自定义的 ObjectMapper,我认为它没有注册 jackson 的 Jdk8Module 和 JSR310Module。

我开了一个issue

我找到的解决方法是在 Global.java

上设置您自己的 ObjectMapper
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);
    }
}

我从 play.libs.Json 来源复制的 mapper.configure 部分