json - Grails Java 8时间JSON简化

标签 json grails java-time

我正在Grails 3.2.3中设计一个简单的Restful预订系统,并希望使用新的Java 8时间库。

@Resource(uri='/reservation', formats=['json'])
class Reservation {

    String groupName
    int groupSize
    LocalDateTime dateTime
    int durationMinutes

    static belongsTo = [calendar:ReservationCalendar]

    static constraints = {
        calendar        blank:false, nullable:false
        groupName       blank:false, size:2..30
        groupSize       blank:false, min:1
        durationMinutes blank:false, min:1
        dateTime        validator: {
                            if (it.isAfter(LocalDateTime.now().plusMinutes(30L))) {
                                return true
                            } else {
                                return ['dateBeforeEarliestReservationTime']
                            }
                        }
    }
}

我在BootStrap.groovy中插入了以下记录:
def init = { servletContext ->
    new ReservationCalendar(reservationObject:"reservable item1", reservationUnitsPerSlot:5).save()
    new Reservation(calendar:1, groupName:"testers1", groupSize:2, dateTime:LocalDateTime.now().plusHours(2L),  durationMinutes:30).save()
    LocalDateTime maxDaysInFuture;


}

现在,当我运行该应用程序时,一切正常。 GET / reservation URI调用index()操作并返回:
[{"id":1,"calendar":{"id":1},"dateTime":{"class":"java.time.LocalDateTime","dayOfMonth":23,"dayOfWeek":{"enumType":"java.time.DayOfWeek","name":"MONDAY"},"dayOfYear":23,"hour":18,"minute":18,"month":{"enumType":"java.time.Month","name":"JANUARY"},"monthValue":1,"nano":629000000,"second":46,"year":2017,"chronology":{"calendarType":"iso8601","class":"java.time.chrono.IsoChronology","id":"ISO"}},"durationMinutes":30,"groupName":"testers1","groupSize":2}]

但是,当我从某个与Java无关的客户端上发布新的保留记录时,我宁愿采用某种方式来不必了解底层数据结构,而可以使用一些干净的输入,例如日期字符串:
[{"id":1,"calendar":{"id":1},"dateTime":"01-23-2017 6:30PM CST","durationMinutes":30,"groupName":"testers1","groupSize":2}]

我一直在阅读Grails文档,但是没有关于如何自定义资源输入/输出的清晰示例。我想要一组字段,例如:
"dateTime":{"dayOfMonth":23,"month":1,"year":2017,"hour":18,"minute":30},

并从这些字段中创建时间对象。

最佳答案

我的解决方法如下:

1)我在我的域类中使用常规的Date对象作为dateTime。我仍在使用Java 8 time api-当我在Date上进行验证和逻辑时,每次都将其转换为LocalDateTime。

LocalDateTime t = LocalDateTime.ofInstant(dateTime.toInstant(), ZoneId.systemDefault());

2)在BootStrap.groovy中,我已经在JSON编码器中注册了友好的输出格式。
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy HH:mm"); 
JSON.registerObjectMarshaller(Reservation) {
    def returnArray = [:]
    returnArray['groupName'] = it.groupName
    returnArray['groupSize'] = it.groupSize
    returnArray['dateTime'] = dateFormat.format(it.dateTime) // other piece of this is in application.yml (grails.databinding.dateFormats)
    return returnArray
}

3)在application.yml中,我定义了grails.databinding.dateFormats以包含相同的友好格式:
grails:
    databinding:
        dateFormats:
            -  "MM-dd-yyyy HH:mm"

结果是一个JSON,其输出如下:
[{"groupName":"testers1","groupSize":2,"dateTime":"01-24-2017 20:47"}]

在执行POST以添加记录的过程中,我只需要提供日期时间作为格式化的字符串即可。
"dateTime":"01-24-2017 21:47"

如果您知道一个解决方案,请随时发布!

关于json - Grails Java 8时间JSON简化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41817096/

相关文章:

unit-testing - 无法在 grails 单元测试中注入(inject)服务类 - 测试失败

java - 我可以只创建一个 DateTimeFormatter 的静态实例吗

javascript - JSON 到 HTML 表 JavaScript 不工作

javascript - 重命名嵌套 JSON 数据集不同级别的变量

java - jackson 打印空的 JSON 字符串

javascript - angularjs 国家代码通过 $http 请求从 jsonfile 中查找

grails - Grails find/findAll操作将无法正常工作?

sql-server - MSSQL服务器连接超时groovy grails应用程序

java - DateTimeFormatter 可以解析,但不能为相同的输入格式化

java - Duration#toDays 和 Duration#toDaysPart 是多余的吗?