How do I add a jackson objectmapper dateformat config into spring mvc config? - spring

I have a problem about jackson 2.1.
My pojo have some date properties, I want turn it to string, I setted it in spring-servlet.xml but it's not usefull.
I don't like use #JsonSerialize(using = JsonDateSerializer.class) on the setter.
this is my configuration:
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd"></constructor-arg>
</bean>
</property>
</bean>
</property>
</bean>

Assuming you are using Spring 3.1, you should customize your mvc-annotation driven tag properties,
as is shown in
Configuring ObjectMapper in Spring
Assuming that your bean declaration is correct I think it should be something like
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd"></constructor-arg>
</bean>
</property>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

My setup is:
<!-- Date Format -->
<bean id="dateFormatter" class="java.text.SimpleDateFormat">
<constructor-arg value="yyyy-MM-dd"/>
</bean>
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="dateFormatter" />
<property name="targetMethod" value="setTimeZone" />
<property name="arguments">
<list>
<ref bean="timeZone"/>
</list>
</property>
</bean>
<!-- End Date Format -->
<!-- Jackson Object Mapper -->
<bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper"/>
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="jacksonObjectMapper" />
<property name="targetMethod" value="configure" />
<property name="arguments">
<list>
<value type="org.codehaus.jackson.map.DeserializationConfig.Feature">FAIL_ON_UNKNOWN_PROPERTIES</value>
<value>false</value>
</list>
</property>
</bean>
<bean id="jacksonDeserializationConfig" class="org.codehaus.jackson.map.DeserializationConfig" factory-bean="jacksonObjectMapper" factory-method="getDeserializationConfig" />
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="jacksonDeserializationConfig" />
<property name="targetMethod" value="setDateFormat" />
<property name="arguments">
<list>
<ref bean="dateFormatter"/>
</list>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="jacksonObjectMapper" />
<property name="targetMethod" value="setDeserializationConfig" />
<property name="arguments">
<list>
<ref bean="jacksonDeserializationConfig"/>
</list>
</property>
</bean>
<!-- End Jackson Object Mapper -->
<!-- JSON provider -->
<bean id="jsonRestProvider" class="org.codehaus.jackson.jaxrs.JacksonJsonProvider">
<property name="mapper" ref="jacksonObjectMapper"/>
</bean>

Related

Not able to ref dataSource from other bean configuartion in Spring

<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="poolName" value="${models.DS_POOL_NAME}" />
</property>
</bean>
<bean id="DBPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="properties">
<bean class="org.apache.commons.configuration2.ConfigurationConverter" factory-method="getProperties">
<constructor-arg>
<bean id="DatabaseConfigurator" class="org.apache.commons.configuration2.DatabaseConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="table" value="sample" />
<property name="keyColumn" value="PROPERTY" />
<property name="valueColumn" value="VALUE" />
<property name="configurationNameColumn" value="GROUP_NAME" />
<property name="configurationName" value="new" />
</bean>
</constructor-arg>
</bean>
</property>
</bean>
when we ref dataSource in DBPlaceholder bean then ${models.DS_POOL_NAME} will showing error because this value is coming from properties

Spring MDP not Consuming Message

I am implementing Spring MDP + JMSTemplate to send and receive the message. The message send mechanism is working fine, however the MDP is not getting invoked. I tried testing the via plain receiver, and was able to retrieve the message, but not via MDP. What could be the problem? I can see the messages getting accumulated in the request queue, but somehow the MDP is not getting trigger. Am I missing anything here in configurations or something else needs to be taken care of?
Here's the Spring Config. The Java class to send and received are pretty much standard ones.
<bean id="cookieRequestListener" class="com.text.jms.mq.mdp.RequestQueueMDP">
<property name="logger" ref="mqLogger" />
<property name="scoringEngine" ref="scoringEngine" />
<property name="mqSender" ref="jmsMQSender" />
</bean>
<bean id="CookieRequestContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="cachedConnectionFactory" />
<property name="destination" ref="jmsRequestQueue" />
<property name="messageListener" ref="cookieRequestListener" />
</bean>
<bean id="jmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="jndiName">
<value>java:/jms/queueCF</value>
</property>
</bean>
<!-- A cached connection to wrap the Queue connection -->
<bean id="cachedConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="jmsConnectionFactory"/>
<property name="sessionCacheSize" value="10" />
</bean>
<!-- jms Request Queue Configuration -->
<bean id="jmsRequestQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="jndiName">
<value>java:/jms/cookieReqQ</value>
</property>
</bean>
<!-- jms Response Queue Configuration -->
<bean id="jmsResponseQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="jndiName">
<value>java:/jms/cookieResQ</value>
</property>
</bean>
<bean id="jmsJMSTemplate" class="org.springframework.jms.core.JmsTemplate" >
<property name="connectionFactory" ref="cachedConnectionFactory" />
</bean>
<!-- jms MQ Utility -->
<bean id="jmsMQSender" class="com.text.jms.util.MQSender">
<property name="jmsTemplate">
<ref bean="jmsJMSTemplate"></ref>
</property>
<property name="defaultDestination">
<ref bean="jmsRequestQueue" />
</property>
<property name="logger" ref="mqLogger" />
</bean>

Spring + MongoDB + Quartz = OptimisticLockingFailureException

on my Spring app I have a job with following setup:
<!-- Spring Quartz Job -->
<bean id="runMeJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="com.pixolut.mrb.ob.ss.SsGateway" />
<property name="targetMethod" value="scheduler" />
</bean>
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="runMeJob" />
<property name="repeatInterval" value="5000" />
<property name="startDelay" value="1000" />
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobDetails">
<list>
<ref bean="runMeJob" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="simpleTrigger" />
</list>
</property>
</bean>
The problem is that when I try to save an object by using the MongoTemplate save function I get OptimisticLockingFailureException
Is it because Quarts doen't support Mongo?
This issue was caused from a null property on my model.

Jackson+Spring3.0.5 custom object mapper

I am having a hard time configuring Jackson on my Spring application. I can get it to work, but it does not seem to accept any kind of configurations. Basically what i'm trying to achieve is have an ObjectMapper that scans for Spring format annotations.
What i am trying is this:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<bean
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper" ref="jacksonObjectMapper" />
</bean>
</list>
</property>
</bean>
<bean id="jacksonObjectMapper" class="ro.softwin.cnfp.ConversionServiceAwareObjectMapper" />
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
<entry key="html" value="text/html" />
</map>
</property>
<property name="viewResolvers">
<list>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean
class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
<property name="prefixJson" value="false" />
<property name="objectMapper" value="jacksonObjectMapper" />
</bean>
</list>
</property>
</bean>
The code for the mapper is :
public class ConversionServiceAwareObjectMapper extends ObjectMapper {
#Autowired
public ConversionServiceAwareObjectMapper(
ConversionService conversionService) {
AnnotationIntrospector introspector = AnnotationIntrospector.pair(
new FormatAnnotationIntrospector(conversionService),
DEFAULT_ANNOTATION_INTROSPECTOR);
this.setDeserializationConfig(this.getDeserializationConfig()
.withAnnotationIntrospector(introspector));
this.setSerializationConfig(this.getSerializationConfig()
.withAnnotationIntrospector(introspector).withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL));
}
}
When initializing the server the following error occurs:
java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [org.codehaus.jackson.map.ObjectMapper] for property 'objectMapper': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:241)
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:470)
... 55 more
I tried switching to a normal view resolver and just having the object mapper in the AnnotationMethodHandler, and that works regarding server start-up, but it just completely ignores any configuration.
I am completely at a loss as to what to do next.
Thanks for any help.
Update :
<property name="objectMapper" value="jacksonObjectMapper" />
with:
<property name="objectMapper" ref="jacksonObjectMapper" />
ref not value.

Java Spring Jackons Date serialization

I'm using Spring MVC and Jackson for JSON de/serialization. But im facing a problem with serializing a date.
By default Jackson serialize a date as an epoch. But i want to serialize it as a ISO date (i.e. 06-10-2011 11:00:00).
The code below is my spring config, but it does not work. It's still returning an epoch date.
So my question is, how can I serialize to a non-epoch date?
<!-- JSON -->
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
<property name="objectMapper" ref="jacksonObjectMapper" />
</bean>
<bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" />
<bean id="jacksonSerializationConfig" class="org.codehaus.jackson.map.SerializationConfig" factory-bean="jacksonObjectMapper" factory-method="getSerializationConfig" />
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="jacksonSerializationConfig" />
<property name="targetMethod" value="setSerializationInclusion" />
<property name="arguments">
<list>
<value type="org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion">NON_NULL</value>
</list>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="jacksonSerializationConfig" />
<property name="targetMethod" value="setDateFormat" />
<property name="arguments">
<list>
<value type="java.text.SimpleDateFormat">yyyy-MM-dd'T'HH:mm:ss.SSSZ</value>
</list>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="jacksonSerializationConfig" />
<property name="targetMethod" value="enable" />
<property name="arguments">
<list>
<value type="org.codehaus.jackson.map.SerializationConfig.Feature">WRITE_DATES_AS_TIMESTAMPS</value>
</list>
</property>
</bean>
Much simpler way to do this now in Spring 3.1.
public class CustomObjectMapper extends ObjectMapper {
public CustomObjectMapper() {
configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);
setDateFormat(new ISO8601DateFormat());
}
}
And then register this as a bean and customize the mvc:annotation-driven element.
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper" ref="customObjectMapper"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="customObjectMapper" class="CustomObjectMapper"/>
Solution using Spring 3.1.3 and Jackson 2.1.0 that works for me (based on Ryans answer and Kornys notes with additional change in Java code "SerializationConfig.Feature" -> "SerializationFeature")
public class DateObjectMapper extends ObjectMapper {
public DateObjectMapper() {
configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
}
Configuration:
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="dateObjectMapper"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="dateObjectMapper" class="DateObjectMapper"/>
I found the following to work with Spring Platform 2.0 (Spring 4.2) and Jackson 2.6.3
pom.xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
</dependency>
applicationContext.xml
<mvc:annotation-driven>
<mvc:message-converters>
<beans:bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<beans:property name="objectMapper">
<beans:bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<beans:property name="featuresToDisable">
<beans:array>
<util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS"/>
</beans:array>
</beans:property>
</beans:bean>
</beans:property>
</beans:bean>
</mvc:message-converters>
</mvc:annotation-driven>
I've fixed my problem. So for reference to others with a similar problem.
I've deleted the following elements in the spring context config xml:
<mvc:annotation-driven/>
and
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="jacksonSerializationConfig" />
<property name="targetMethod" value="setDateFormat" />
<property name="arguments">
<list>
<value type="java.text.SimpleDateFormat">yyyy-MM-dd'T'HH:mm:ss.SSSZ</value>
</list>
</property>
Then I added the following:
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="order" value="1" />
</bean>
and changed the following:
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="jacksonSerializationConfig" />
<property name="targetMethod" value="enable" />
<property name="arguments">
<list>
<value type="org.codehaus.jackson.map.SerializationConfig.Feature">WRITE_DATES_AS_TIMESTAMPS</value>
</list>
</property>
in
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="jacksonSerializationConfig" />
<property name="targetMethod" value="disable" />
<property name="arguments">
<list>
<value type="org.codehaus.jackson.map.SerializationConfig.Feature">WRITE_DATES_AS_TIMESTAMPS</value>
</list>
</property>
After this Spring was able to serialize my date into json as a ISO date.

Resources