【问题标题】:Change date format in DTO JSON on returning through @ResponseBody通过@ResponseBody 返回时更改 DTO JSON 中的日期格式
【发布时间】:2019-03-13 12:23:01
【问题描述】:

我只想更改 @ResponseBody 返回的 DTO 中的日期格式

我的问题不是 this question,因为我的输出是 JSON 列表,我在 Postman 上打印它,而不是使用带有 JS 和其他 UI 功能的视图。

它也不是 this one,因为我返回的是 JSON 列表,而不仅仅是 Date 对象。

它是 this one 的扩展,但我不认为 @ 987654328@是罪魁祸首。

我在使用@ResponseBody 返回列表时得到日期的时间戳值

我的自定义代码-

@RequestMapping(value = "/my/report", method = RequestMethod.POST)
@ResponseBody
public List<OrderWsDTO> createReport() {
    //stuff
    return Optional.ofNullable(orderDataList)
            .orElse(Collections.emptyList())
            .stream()
            .map(orderData -> getDataMapper().map(orderData, OrderWsDTO.class, fields))
            .collect(Collectors.toList());
}

映射器是: map:162, ConfigurableMapper (ma.glasnost.orika.impl)

getDataMapper().mapAsList(orderDataList, OrderWsDTO.class, fields) 的同样问题:

@RequestMapping(value = "/my/report", method = RequestMethod.POST)
@ResponseBody
public List<OrderWsDTO> createReport() {
    //stuff
    return getDataMapper().mapAsList(orderDataList, OrderWsDTO.class, fields);
}

OrderWsDTO 是一个 DTO,带有 getter 和 setter,日期字段为 java.util.Date

在邮递员中,我可以看到日期格式为:
@ 987654335@

返回 OrderWsDTO 而不是 List&lt;OrderWsDTO&gt; 的相同调用会更改日期格式。它将日期打印为2019-03-13T12:10:05+0000,格式为:yyy-MM-dd'T'HH:mm:ss.SSXXX

@RequestMapping(value = "/my/report", method = RequestMethod.POST)
@ResponseBody
public OrderWsDTO createReport() {
    //stuff
    return getDataMapper().map(orderData, OrderWsDTO.class, fields);
}


为什么以List&lt;DTO&gt;DTO 打印的日期显示两种不同的格式?

另外,它从哪里获得格式:yyy-MM-dd'T'HH:mm:ss.SSXXX


编辑 1:

日期在这里被格式化: de.hybris.platform.webservicescommons.jaxb.adapters.DateAdapter#marshal()
格式:yyyy-MM-dd'T'HH:mm:ssZ

现在,如何重写这个类?


编辑 2:

我无法覆盖jaxbContextFactory,它具有修改日期的适配器列表。 jaxbContextFactory 看起来像-

<alias name="defaultJaxbContextFactory" alias="jaxbContextFactory"/>
<bean id="defaultJaxbContextFactory" class="de.hybris.platform.webservicescommons.jaxb.MoxyJaxbContextFactoryImpl">
    <property name="wrapCollections" value="${webservicescommons.messageconverters.context.wrapCollections}" />
    <property name="analysisDepth" value="${webservicescommons.messageconverters.context.analysisDepth}" />
    <property name="typeAdapters" ref="jaxbTypeAdaptersList" />
    <property name="subclassRegistry" ref="subclassRegistry" />
    <property name="otherClasses" ref="jaxbContextClasses" />
    <property name="metadataSourceFactory" ref="metadataSourceFactory" />
    <property name="excludeClasses"  ref ="jaxbContextFactoryExcludeClasses"/>
</bean>

在我的自定义代码中覆盖此 bean 时,它仍在为 typeAdapters 选择旧值。有趣的是,它正在用我的自定义属性替换其他属性。

我的自定义覆盖 bean-

<alias name="defaultJaxbContextFactory" alias="jaxbContextFactory"/>
<bean id="defaultJaxbContextFactory" class="de.hybris.platform.webservicescommons.jaxb.MoxyJaxbContextFactoryImpl">
    <property name="wrapCollections" value="false" />
    <property name="analysisDepth" value="30" />
    <property name="typeAdapters" ref="mylist" />
    <property name="subclassRegistry" ref="subclassRegistry" />
    <property name="otherClasses" ref="jaxbContextClasses" />
    <property name="metadataSourceFactory" ref="metadataSourceFactory" />
    <property name="excludeClasses"  ref ="jaxbContextFactoryExcludeClasses"/>
</bean>

<util:list id="mylist">
    <value>com.myproject.mymodule.myadapter</value>
    <value>de.hybris.platform.webservicescommons.jaxb.adapters.VariableMapAdapter</value>
    <value>de.hybris.platform.webservicescommons.jaxb.adapters.XSSStringAdapter</value>
</util:list>

对于typeAdapters,它总是选择值-

<property name="typeAdapters">
        <list>
            <value>de.hybris.platform.webservicescommons.jaxb.adapters.DateAdapter</value>
            <value>de.hybris.platform.webservicescommons.jaxb.adapters.StringMapAdapter</value>
            <value>de.hybris.platform.webservicescommons.jaxb.adapters.XSSStringAdapter</value>
        </list>
    </property>

编辑 3:

我尝试将 mycustomaddon-web-spring.xml 中的 bean 覆盖为 -

<bean id="customJaxbContextFactory" parent="jaxbContextFactory">
    <property name="metadataSourceFactory" ref="customMetadataSourceFactory" />
    <property name="typeAdapters">
        <list>
            <value>myproject.adapters.DateAdapter</value>
            <value>de.hybris.platform.webservicescommons.jaxb.adapters.StringMapAdapter</value>
            <value>de.hybris.platform.webservicescommons.jaxb.adapters.XSSStringAdapter</value>
        </list>
    </property>
</bean>

我在acceleratoraddon/web 中添加了自定义适配器类,即myproject.adapters.DateAdapter。 不过没有成功。

【问题讨论】:

  • 你得到的格式是ISO 8601。我不知道它是如何产生的,但如果可以的话,建议使用它。当您使用 Java 8 或更高版本时,为什么要使用早已过时且设计不佳的 Date 类?您可能想要来自java.time, the modern Java date and time APIInstant
  • @OleV.V. : 不是一个选项。 OrderDataOrderWsDTO 都已在 OTB 代码中定义。
  • Orika 正在成功地完成它的工作,我建议你看看你的 JSON 编组器。由于您使用的是 Spring,我将猜测您使用的是 Jackson。您将需要配置所需的格式。此链接可能有助于您入门stackoverflow.com/q/4823358/1018903 && baeldung.com/jackson-serialize-dates

标签: java spring spring-mvc marshalling hybris


【解决方案1】:

“jaxbContextFactory”bean 首先在“webservicescommons-spring.xml”中定义,它在应用程序上下文中创建 bean。因此,当您使用 (customExtension)-spring.xml 覆盖自定义扩展中的 bean 时,它只是覆盖应用程序上下文中的 bean。有关 Hybris 中上下文加载的更多信息,请访问 here

您的 cmets 中提到的 typeAdapters 属性在另一个 bean 中定义,该 bean 定义在“jaxb-converters-spring.xml”中

<bean id="customJaxbContextFactory" parent="jaxbContextFactory">
        <property name="metadataSourceFactory" ref="customMetadataSourceFactory" />
        <property name="typeAdapters">
            <list>
                <value>de.hybris.platform.webservicescommons.jaxb.adapters.DateAdapter</value>
                <value>de.hybris.platform.webservicescommons.jaxb.adapters.StringMapAdapter</value>
                <value>de.hybris.platform.webservicescommons.jaxb.adapters.XSSStringAdapter</value>
            </list>
        </property>
    </bean>

由于 jaxb-converters-spring-xml 中定义的 bean 被加载到 WebApplicationContext 中,因此您需要使用 (customExtension)-web-spring.xml 覆盖此 bean,您可以在自定义扩展的 websrc 中定义 bean 和相应的类。

【讨论】:

  • 没有成功。我在我的 custom-web-spring.xml 中复制了整个 bean 定义,同时只用我的自定义日期适配器替换了日期适配器。我的自定义模块是一个插件,所以我在 myaddon/acceleratoraddon/web/src/com/myproject/myaddon/adapters/IndDateAdapter.java 中创建了日期适配器条目
  • 您的插件加载正确吗?您还可以检查哪个日期适配器是 groovy 返回: spring.getBean("jaxbContextFactory").getTypeAdapters();
  • 是的。我可以点击插件中声明的控制器。此外,我可以看到自定义日期适配器被复制到我原来的 webservicescomons 中。运行 groovy 并在调试时检查 bean 值会为 OTB 适配器提供相同的值,而不是我的自定义适配器。如果它没有要求太多,您可以在您的代码库中尝试一下。您可以使用任何 OTB 进行检查,调用打印日期,例如:localhost:9002/customcommercewebservices/v2/basesite/orders/…
猜你喜欢
  • 1970-01-01
  • 2014-04-11
  • 1970-01-01
  • 1970-01-01
  • 2015-11-24
  • 1970-01-01
  • 2022-08-11
  • 2014-07-09
  • 1970-01-01
相关资源
最近更新 更多