Изменить формат даты в DTO JSON при возврате через @ResponseBody - PullRequest
2 голосов
/ 13 марта 2019

Я просто хочу изменить формат даты в моем DTO, возвращаемом @ ResponseBody

Мой вопрос не , этот вопрос , поскольку мои выходные данные представляют собой список JSON, и я печатаю его на Postman вместо использования представления с JS и другими функциями пользовательского интерфейса.

Это не этот , потому что я возвращаю список JSON, а не просто объект Date .

Это расширение этого , но я не думаю, что Orika mapper виновник.

Я получаю значение метки времени даты при возврате списка с помощью @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());
}

Картограф: карта: 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 с геттерами и сеттерами и полем даты java.util.Date.

В почтальоне я могу видеть формат даты как:
"date": "1552476861991"

Тот же самый точный вызов, который возвращает OrderWsDTO вместо List<OrderWsDTO>, изменяет формат даты. Дата печатается как 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<DTO> и 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. Интересно, что он заменяет другие свойства моими пользовательскими свойствами.

Мой пользовательский переопределенный бин -

<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 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>

Я добавил пользовательский класс адаптера, т.е. myproject.adapters.DateAdapter в acceleratoraddon/web. Не вышло, хотя.

1 Ответ

1 голос
/ 16 марта 2019

Компонент 'jaxbContextFactory' впервые определен в ' webservicescommons-spring.xml ', который создает компонент в контексте приложения.Поэтому, когда вы переопределяете bean-компонент в своем пользовательском расширении с помощью (customExtension) -spring.xml, он просто переопределяет bean-компонент в контексте приложения.Более подробную информацию о загрузке контекста в Hybris можно найти здесь .

Свойство typeAdapters, упомянутое в ваших комментариях, определено в другом bean-компоненте, который определен в ' jaxb-convertters-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>

Поскольку bean-компоненты, определенные в jaxb-convertters-spring-xml , загружаются в WebApplicationContext, вам необходимо переопределить этот bean-компонент с помощью (customExtension) -web-spring.xml, где вы можете определить bean-компонент и соответствующий класс в websrc вашего пользовательского расширения.

...