I simply want to change the date format in my DTO returned by @ResponseBody
My question is not this question as my output is a JSON List and I am printing it on Postman instead of using a view with JS and other UI features.
It's not this one as well because I am returning a JSON List, not just the Date object.
It is an extension of this one, but I don't think Orika mapper
is the culprit.
I am getting the timestamp value of date on returning the List using @ResponseBody
.
My custom code-
@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());
}
The mapper is: map:162, ConfigurableMapper (ma.glasnost.orika.impl)
Same issue with 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
is a DTO with getters and setters and a date field that is java.util.Date
.
In postman I can see the date format as : "date": "1552476861991"
The same exact call which returns OrderWsDTO
instead of List<OrderWsDTO>
changes the date format. It is printing the date as 2019-03-13T12:10:05+0000
which is format : 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);
}
Why is the date showing two different formats when printed in List<DTO>
and DTO
?
Also, where is it getting the format : yyy-MM-dd'T'HH:mm:ss.SSXXX
?
Edit 1:
The date is getting formatted here:
de.hybris.platform.webservicescommons.jaxb.adapters.DateAdapter#marshal()
Format : yyyy-MM-dd'T'HH:mm:ssZ
Now, how to override this class?
Edit 2:
I am not able to override the jaxbContextFactory
which has the list of adapters to modify the date. The jaxbContextFactory
looks like-
<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>
On overriding this bean in my custom code it is still picking the old values for typeAdapters
. Interestingly, it is replacing other properties with my custom properties.
My custom overridden 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>
For typeAdapters
it is always picking the values-
<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>
Edit 3:
I tried overriding the bean in mycustomaddon-web-spring.xml
as -
<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>
I have added the custom adapter class i.e. myproject.adapters.DateAdapter
in acceleratoraddon/web
.
Did not work out though.
The 'jaxbContextFactory' bean is first defined in the 'webservicescommons-spring.xml' which creates the bean in the application context. So when you override the bean in your custom extension using (customExtension)-spring.xml, it is just overriding the bean in the application context. More information about context loading in Hybris can be found here.
The typeAdapters property mentioned in your comments is defined in another bean which is defined in the 'jaxb-converters-spring.xml'
Since the beans defined in the jaxb-converters-spring-xml are loaded in the WebApplicationContext, you will need to override this bean using the (customExtension)-web-spring.xml where you can define the bean and corresponding class in the websrc of your custom extension.