Grails JSON Marshaller显示与原始日期不同的日期值

Fer*_*deh 1 grails json

在我的Grails应用程序中,从数据库中读取的原始日期等于:

{ endDate=2015-10-19 19:00:00.0}
Run Code Online (Sandbox Code Playgroud)

而JSON结果是:

{"endDate": "2015-10-19T16:00:00Z"}
Run Code Online (Sandbox Code Playgroud)

我认为这可能与时区转换有关.如何在JSON中没有任何时区转换的情况下显示原始日期?

Dón*_*nal 5

根据这段时间你在,区域2015-10-19 19:00:00.02015-10-19T16:00:00Z可能不是不同的时间,他们可能是同一时间(即时)只是不同的表示.

在我的例子中,我使用自定义编组器来确保API的JSON响应中的时间始终使用UTC时区.我的自定义marshaller看起来像这样:

import org.springframework.stereotype.Component

@Component
class DateMarshaller implements CustomMarshaller {

    @Override
    def getSupportedTypes() {
        Date
    }

    @Override
    Closure getMarshaller() {
        { Date date ->

            TimeZone tz = TimeZone.getTimeZone('UTC')
            date?.format("yyyy-MM-dd'T'HH:mm:ss'Z'", tz)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

记得注册这个marshaller用于Spring bean扫描的包Config.groovy.它实现的接口是:

interface CustomMarshaller {

    /**
     * Indicates the type(s) of object that this marshaller supports
     * @return a {@link Class} or collection of {@link Class} 
     * if the marshaller supports multiple types
     */
    def getSupportedTypes()

    Closure getMarshaller()
}
Run Code Online (Sandbox Code Playgroud)

然后我有一个服务,注册CustomMarshaller相关类型的所有实例:

import grails.converters.JSON
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware

import javax.annotation.PostConstruct

class MarshallerRegistrarService implements ApplicationContextAware {

    static transactional = false

    ApplicationContext applicationContext

    // a combination of eager bean initialization and @PostConstruct ensures that the marshallers are registered when
    // the app (or a test thereof) starts
    boolean lazyInit = false

    @PostConstruct
    void registerMarshallers() {

        Map<String, CustomMarshaller> marshallerBeans = applicationContext.getBeansOfType(CustomMarshaller)

        marshallerBeans.values().each { CustomMarshaller customMarshaller ->

            customMarshaller.supportedTypes.each { Class supportedType ->
                JSON.registerObjectMarshaller supportedType, customMarshaller.marshaller
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个相当复杂的解决方案,但在我的情况下,我使用的是Grails 2.5.X. 如果我使用的是Grails 3.X,我会尝试使用JSON视图.