我正在Grails 3.2.3中设计一个简单的宁静预订系统,并希望使用新的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 无关的客户端去 POST 一个新的保留记录时,我宁愿有某种方式不必了解底层数据结构并有一些干净的输入,例如日期字符串:
[{"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"
如果您知道一个更时髦的解决方案,请随时发布!