Spring Social Linkedin - SignIn - spring-social-linkedin

I am new to Spring social and trying to config spring social signin for linkedin.
My spring config file below,
<context:component-scan base-package="com.tc.web">
<context:include-filter type="regex"
expression="(service|controller|component)\..*" />
</context:component-scan>
<bean id="connectionFactoryLocator"
class="org.springframework.social.connect.support. ConnectionFactoryRegistry">
<property name="connectionFactories">
<list>
<bean
class="org.springframework.social.linkedin.connect .LinkedInConnectionFactory">
<constructor-arg value="key........" />
<constructor-arg value="secret .........." />
</bean>
</list>
</property>
</bean>
<bean id="textEncryptor" class="org.springframework.security.crypto.encrypt .Encryptors"
factory-method="noOpText" />
<bean id="usersConnectionRepository"
class="org.springframework.social.connect.jdbc.Jdb cUsersConnectionRepository">
<constructor-arg ref="dataSource" />
<constructor-arg ref="connectionFactoryLocator" />
<constructor-arg ref="textEncryptor" />
</bean>
<bean id="connectionRepository" factory-method="createConnectionRepository"
factory-bean="usersConnectionRepository" scope="request">
<constructor-arg value="#{request.userPrincipal.name}" />
<aop:scoped-proxy proxy-target-class="false" />
</bean>
<bean id="signInAdapter" class="com.tc.web.social.signin.SocialSignInAdapte r" />
<bean class="org.springframework.social.connect.web.Prov iderSignInController">
<!-- relies on by-type autowiring for the constructor-args -->
<constructor-arg ref="signInAdapter" />
<property name="applicationUrl" value="link" />
<property name="signUpUrl" value="link" />
<property name="signInUrl" value="link" />
</bean>
My SocialSignInAdapter.java is,
public class SocialSignInAdapter implements SignInAdapter{
#Override
public String signIn(String userId, Connection<?> connection, NativeWebRequest request) {
System.out.println("User Id is ===>>> "+userId);
System.out.println("Connection is ====>>> "+connection);
return null;
}
}
In Login.jsp,
<li class="linkedin"> </li>
When I click the above linkedin link, i get 404 error.
I guess my app is unable to find the ProviderSignInController for the request, ://dom:8080/myApp/signin/linkedin.
I suspect the below config in spring xml.
<context:component-scan base-package="com.tc.web">
<context:include-filter type="regex"
expression="(service|controller|component)\..*" />
</context:component-scan>
I have all my controller inside the package com.tc.web. But the ProviderSignInController is in Spring package and my app is unable to find it.
I tried the below as well.
<context:component-scan base-package="com.tc.web,org.springframework.social.con nect.web">
<context:include-filter type="regex"
expression="(service|controller|component)\..*" />
</context:component-scan>
I got ambigous mapping error for ProviderSignInController with the above config.
So, I removed the
<bean class="org.springframework.social.connect.web.Prov iderSignInController">
<!-- relies on by-type autowiring for the constructor-args -->
<constructor-arg ref="signInAdapter" />
<property name="applicationUrl" value="link" />
<property name="signUpUrl" value="link" />
<property name="signInUrl" value="link" />
</bean>
from my spring xml. But still I am getting the 404 error.
Could anyone help me on this please ..........
Thanks,
Baskar.S

The Controller that handles signin requests is org.springframework.social.connect.web.ProviderSignInController (present in spring-social-web-x.x.x.jar)
The Controller method is
#RequestMapping(value="/{providerId}", method=RequestMethod.POST)
public RedirectView signIn(#PathVariable String providerId, NativeWebRequest request)
So, as you can see, it only accepts POST requests. You will have to change the anchor link tag to a button that triggers a form submit.
e.g.
<form action="<c:url value="/signin/linkedin" />" method="POST" id="frmLiConnect"></form>
Secondly, in order for the Spring Controller, extend the ProviderSignInController with your own dummy Controller so that the Spring class is accessible.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.social.connect.ConnectionFactoryLocator;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.connect.web.ProviderSignInController;
import org.springframework.social.connect.web.SignInAdapter;
import org.springframework.stereotype.Controller;
#Controller
public class SigninController extends ProviderSignInController {
#Autowired
public SigninController(ConnectionFactoryLocator connectionFactoryLocator,
UsersConnectionRepository usersConnectionRepository,
SignInAdapter signInAdapter) {
super(connectionFactoryLocator, usersConnectionRepository, signInAdapter);
// TODO Auto-generated constructor stub
}
}
For more details, you can also refer to the Spring Social Showcase examples at the below link.
https://github.com/spring-projects/spring-social-samples/tree/master/spring-social-showcase/src/main/java/org/springframework/social/showcase/signin
Hope this helps.

Related

How to set connection timeout with OAuth2RestTemplate while fetching access token

We are able to fetch access token using attached code snapshot but didn't find any way to set connection timeout as we do with spring restTemplate.Is there any way to set a connection timeout with OAuth2RestTemplate.
<bean id="bean" class="com.test.Provider">
<constructor-arg name="context" ref="context" />
<constructor-arg name="detail" ref="resourceDetails" />
</bean>
<bean id="context" class="org.springframework.security.oauth2.client.DefaultOAuth2ClientContext">
<constructor-arg name="accessTokenRequest" ref="request" />
</bean>
<bean id="request" class="org.springframework.security.oauth2.client.token.DefaultAccessTokenRequest"/>
<bean id="resourceDetails" class="org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails"/>
A little late to the party, but in case you're wondering how to do this with springboot, this is a way:
#Bean
protected OAuth2RestTemplate oauth2RestTemplate(ClientHttpRequestFactory clientHttpRequestFactory) {
OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(oAuthDetails());
oAuth2RestTemplate.setRequestFactory(clientHttpRequestFactory);
return oAuth2RestTemplate;
}
#Bean
protected ClientHttpRequestFactory requestFactory() {
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(10000); //timeout in milliseconds
requestFactory.setReadTimeout(10000); //timeout in milliseconds
return requestFactory;
}
Where oAuthDetails() is a method that reads the oauth configuration properties, similar to this:
#Bean
#ConfigurationProperties("path.to.your.oauth.properties.on.yml")
protected ClientCredentialsResourceDetails oAuthDetails() {
return new ClientCredentialsResourceDetails();
}
If I'm right, the way you give the connection timeout to the Spring RestTemplate as a constructor argument is through giving a ClientHttpRequestFactory as an argument to the constructor
RestTemplate(ClientHttpRequestFactory requestFactory)
Using for example the HttpComponentsClientHttpRequestFactory, one can set the connection timeout to the RestClient in XML as follows
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<constructor-arg name="requestFactory">
<bean id="requestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
<property name="connectTimeout" value="2000" />
<property name="readTimeout" value="10000" />
</bean>
</constructor-arg>
</bean>
RestTemplate also offers a way to set the requestFactory property through a setter, which it inherits from InterceptingHttpAccessor, and in fact the constructor itself seems to use that setter to set the requestFactory given as constructor argument.
Thus, you can set the requestFactory for the OAuth2RestTemplate through the setter. In XML:
<bean id="oauth2RestTemplate" class="org.springframework.security.oauth2.client.OAuth2RestTemplate">
<constructor-arg name="resource" ref="resourceDetails" />
<constructor-arg name="context" ref="context" />
<property name="requestFactory">
<bean id="requestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
<property name="connectTimeout" value="2000" />
<property name="readTimeout" value="10000" />
</bean>
</property>
</bean>
Or, in your case, you can for example give your class com.test.Provider a constructor argument requestFactory and then use that to set the request factory in the OAuth2RestTemplate as follows:
XML:
<bean id="bean" class="com.test.Provider">
<constructor-arg name="context" ref="context" />
<constructor-arg name="resourceDetails" ref="resourceDetails" />
<constructor-arg name="requestFactory">
<bean id="requestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
<property name="connectTimeout" value="2000" />
<property name="readTimeout" value="10000" />
</bean>
</constructor-arg>
</bean>
And in your code set
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(this.resourceDetails, this.context);
restTemplate.setRequestFactory(this.requestFactory);
String tokenString = restTemplate.getAccessToken().getValue();
after setting the value of this.requestFactory in the constructor.
PS. I would prefer to create a single OAuth2RestTemplate for the entire class as a private field and reuse it in that class, unless you have a reason to create a new one for each request. You could create it in the constructor, as you are giving the context and details as constructor arguments, or then in a post-construct/init-method. Or even give it as a constructor-argument or as a property to your class in the XML, in case the context and resourceDetails are not used outside the restTemplate.
EDIT
After doing some more research, it seems that the problem might be harder than I thought. OAuth2RestTemplate uses an AccessTokenProvider to get the access tokens, by default it uses a chain of AccessTokenProviders through a instance of AccessTokenProviderChain in order to support the different types of grant types. It seems that each of these uses their own RestTemplate to send the requests to obtain the access token. Unfortunately, it seems that OAuth2RestTemplate doesn't offer a simple way to set the requestFactory of the default AccessTokenProviders' restTemplates.
So, if the solution that I proposed above is not working (which I suspect), I would use the following approach which I believe to work.
All the default AccessTokenProviders in Spring Security Oauth2 extend the class OAuth2AccessTokenSupport, which also is the class that creates the internal RestTemplate. Fortunately, this class offers a setter to set the requestFactory of the internal RestTemplate. So, one can create for example an instance of a ClientCredentialsAccessTokenProvider and give set the requestFactory through the setRequestFactory(...) method. In XML:
<bean id="clientCredentialsAccessTokenProvider class="org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider">
<property name="requestFactory">
<bean id="requestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
<property name="connectTimeout" value="2000" />
<property name="readTimeout" value="10000" />
</bean>
</property>
</bean>
For some reason the OAuth2RestTemplate doesn't offer a way to access the default AccessTokenProviders, but one can set them through the setAccessTokenProvider(AccessTokenProvider accessTokenProvider) setter. To replicate the original default behaviour of the OAuth2RestTemplate, one would have to give an instance of a AccessTokenProviderChain, together with four default AccessTokenProviders and set their requestFactories. However, as you know that the accessed resource is of type ClientCredentialsResourceDetails, it suffices to set a single ClientCredentialsAccessTokenProvider in the setAccessTokenProvider(...) setter and set the requestFactory of the ClientCredentialsAccessTokenProvider.
So we would get the following code:
XML:
<bean id="bean" class="com.test.Provider">
<constructor-arg name="context" ref="context" />
<constructor-arg name="resourceDetails" ref="resourceDetails" />
<constructor-arg name="accessTokenProvider" ref="clientCredentialsAccessTokenProvider" />
</bean>
<bean id="clientCredentialsAccessTokenProvider" class="org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider">
<property name="requestFactory">
<bean id="requestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
<property name="connectTimeout" value="2000" />
<property name="readTimeout" value="10000" />
</bean>
</property>
</bean>
And in your code, set the AccessTokenProvider:
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(this.resourceDetails, this.context);
restTemplate.setAccessTokenProvider(this.accessTokenProvider);
String tokenString = restTemplate.getAccessToken().getValue();
after setting the value of this.accessTokenProvider in the constructor. If you decide to create the OAuth2RestTemplate in the XML, you can write
<bean id="oauth2RestTemplate" class="org.springframework.security.oauth2.client.OAuth2RestTemplate">
<constructor-arg name="resource" ref="resourceDetails" />
<constructor-arg name="context" ref="context" />
<property name="accessTokenProvider" ref="clientCredentialsAccessTokenProvider" />
</bean>
where the bean "clientCredentialsAccessTokenProvider" is defined as above.
Hope that this works.
One issue with above solution is that ClientCredentialsAccessTokenProvider uses a bit enhanced requestFactory:
private ClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory() {
protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
super.prepareConnection(connection, httpMethod);
connection.setInstanceFollowRedirects(false);
connection.setUseCaches(false);
...
}
...
};
So in order to preserve the original functionality you should set up the same implementation of the factory.

Spring batch read from xml file and write to Database. need step1 auto generated key for step2

As seen in below code in step1 I'm reading users.xml and writing to database now in step2 I'm reading from userdetails.xml and writing to database but I need step1 auto generated key of tbl_user for step2. How Can I do that?
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch-2.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<import resource="../config/context.xml" />
<import resource="../config/database.xml" />
<bean id="xmlItemReader1" class="org.springframework.batch.item.xml.StaxEventItemReader">
<property name="resource" value="file:xml/outputs/users.xml" />
<property name="fragmentRootElementName" value="user" />
<property name="unmarshaller" ref="userUnmarshaller"/>
</bean>
<bean id="xmlItemReader2" class="org.springframework.batch.item.xml.StaxEventItemReader">
<property name="resource" value="file:xml/outputs/userdetails.xml" />
<property name="fragmentRootElementName" value="userdetail" />
<property name="unmarshaller" ref="userUnmarshaller"/>
</bean>
<bean id="itemProcessor1" class="com.qmetry.recovery.mapper.UserItemProcessor" />
<bean id="itemProcessor2" class="com.qmetry.recovery.mapper.UserDetailItemProcessor" />
<job id="testJob2" xmlns="http://www.springframework.org/schema/batch">
<step id="step2_1">
<tasklet transaction-manager="transactionManager">
<chunk reader="xmlItemReader1" writer="databaseItemWriter1" processor="itemProcessor1"
commit-interval="100" />
</tasklet>
<listeners>
<listener ref="testListener" />
</listeners>
</step>
<step id="step2_2">
<tasklet transaction-manager="transactionManager">
<chunk reader="xmlItemReader2" writer="databaseItemWriter2" processor="itemProcessor1"
commit-interval="100" />
</tasklet>
</step>
</job>
<bean id="testListener" class="com.qmetry.recovery.mapper.TestListener" scope="step" />
<bean id="databaseItemWriter1" class="org.springframework.batch.item.database.JdbcBatchItemWriter">
<property name="dataSource" ref="dataSource" />
<property name="sql">
<value>
<![CDATA[
insert into TBL_USER(USERNAME,EMAILID)
values (?, ?)
]]>
</value>
</property>
<!--We need a custom setter to handle the conversion between Jodatime LocalDate and MySQL DATE BeanPropertyItemSqlParameterSourceProvider-->
<property name="itemPreparedStatementSetter">
<bean class="com.qmetry.recovery.mapper.UserItemPreparedStatementSetter"/>
</property>
</bean>
<bean id="databaseItemWriter2" class="org.springframework.batch.item.database.JdbcBatchItemWriter">
<property name="dataSource" ref="dataSource" />
<property name="sql">
<value>
<![CDATA[
insert into TBL_USERDETAIL(USERID,CONTACT)
values (?, ?)
]]>
</value>
</property>
<!--We need a custom setter to handle the conversion between Jodatime LocalDate and MySQL DATE BeanPropertyItemSqlParameterSourceProvider-->
<property name="itemPreparedStatementSetter">
<bean class="com.qmetry.recovery.mapper.UserDetailItemPreparedStatementSetter"/>
</property>
</bean>
users.xml
<?xml version="1.0" encoding="UTF-8"?><users>
<user>
<userId>1</userId>
<userName>Taher</userName>
<emailId>taher.tinwala#hotmail.com</emailId>
</user>
</users>
userdetails.xml
<?xml version="1.0" encoding="UTF-8"?><userdetails>
<userdetail>
<userDetailId>1</userDetailId>
<userId__TblUser>1</userId__TblUser>
<contact>1111111111</contact>
</userdetail>
<userdetail>
<userDetailId>2</userDetailId>
<userId__TblUser>1</userId__TblUser>
<contact>2222222222</contact>
</userdetail>
<userdetail>
<userDetailId>4</userDetailId>
<userId__TblUser>1</userId__TblUser>
<contact>4444444444</contact>
</userdetail>
</userdetails>
You need to pass data to a future step. For explantory documentation see http://docs.spring.io/spring-batch/trunk/reference/html/patterns.html#passingDataToFutureSteps
I have implemented the example from the documentation and adjusted it to your configuration with some assumptions here and there.
During the read (or the write, it depends when you get the data that you want to pass) in step 1 you need to store the data in the StepExecution. Add to your xmlItemReader the following:
public class YourItemReader implements ItemReader<Object>
private StepExecution stepExecution;
public void read(Object item) throws Exception {
// ...
ExecutionContext stepContext = this.stepExecution.getExecutionContext();
stepContext.put("tbl_user", someObject);
}
#BeforeStep
public void saveStepExecution(StepExecution stepExecution) {
this.stepExecution = stepExecution;
}
Your xml will look like this:
<step id="step2_1">
<tasklet transaction-manager="transactionManager">
<chunk reader="xmlItemReader1" writer="databaseItemWriter1" processor="itemProcessor1" commit-interval="100" />
</tasklet>
<listeners>
<listener ref="testListener" />
<listener ref="promotionListener"/>
</listeners>
</step>
Add the promotionListener bean:
<beans:bean id="promotionListener" class="org.springframework.batch.core.listener.ExecutionContextPromotionListener">
<beans:property name="keys" value="tbl_key"/>
</beans:bean>
And finally you need to retrieve the value in step 2. Again asuming you need it in the reader of step 2 you reader in step 2 needs the following code added:
public class YourItemReader2 implements ItemReader<Object>
private Object someObject;
#BeforeStep
public void retrieveInterstepData(StepExecution stepExecution) {
JobExecution jobExecution = stepExecution.getJobExecution();
ExecutionContext jobContext = jobExecution.getExecutionContext();
this.someObject = jobContext.get("tbl_key");
}
Now you have acces to the value read in step 1.
EDIT - adding some example configuration for an extra read step:
After step 1 add a simple step 2 with the following reader to get the new value from the database
<bean id="itemReader" class="org.springframework.batch.item.database.JdbcCursorItemReader"
scope="step">
<property name="dataSource" ref="dataSource" />
<property name="sql">
<value>
<![CDATA[
YOUR SELECT STATEMENT
]]>
</value>
</property>
<property name="rowMapper" ref="rowMapper" />
</bean>
And a simple rowMapper bean
<bean id="rowMapper" class="exampleRowMapper" />
You will have to write your exampleRowMapper obviously to reflect the data your fetching. For example:
public class ExampleRowMapper implements ParameterizedRowMapper<String> {
#Override
public String mapRow(ResultSet rs, int rowNum) throws SQLException {
return String.valueOf(rs.getString(1));
}
}
In your dummywriter you add the stepexecution and you will store your value in the step execution context.:
public class DummyItemWriter implements ItemWriter<Object> {
private StepExecution stepExecution;
#Override
public void write(List<? extends Object> item) throws Exception {
ExecutionContext stepContext = this.stepExecution.getExecutionContext();
stepContext.put("someKey", someObject);
}
}
And the bean for the writer:
<bean id="savingDummyWriter" class="your.package.DummyItemWriter" />
And wrap the reader and writer in a step.
<step id="step2">
<tasklet>
<chunk reader="itemReader" writer="dummyItemWriter" commit-interval="1" />
</tasklet>
<listeners>
<listener ref="promotionListener"/>
</listeners>
</step>

Return a JSONObject through Spring MappingJackson2JsonView

I Have xml and json output view for my spring project. I'm using spring 4 version and This is the my ViewResolver xml file.
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</map>
</property>
<property name="defaultViews">
<list>
<!-- JSON View -->
<bean
class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
</bean>
<!-- JAXB XML View -->
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.rest.dto.SportInfoDtoList</value>
</list>
</property>
</bean>
</constructor-arg>
</bean>
</list>
</property>
<property name="ignoreAcceptHeader" value="true" />
</bean>
I want to pass Jackson JSONObject through my controller using ModelAndView.
#RequestMapping(value="stat", method=RequestMethod.POST)
public ModelAndView getSeasonteamStat(#ModelAttribute(value="statDto") StatDto statDto){
ModelAndView model = new ModelAndView();
try{
String seasonteamstatStr = GuideStatClient.getSeasonTeamStats();
JSONObject seasonteamstat = new JSONObject(seasonteamstatStr);
model.addObject("seasonteamstat", seasonteamstat);
return model;
} catch (Exception e){
return model;
}
}
If I return seasonteamstatStr it will return successfully. But I need to pass this string as a json objet. This is a huge object so I dont want to map it into java objects using JAXB.
So is there have any way to pass this string as a json. I tried jackson and gson JSONObject. Thanks in advance
Annotate your method with #ResponseBody which indicates a method return value should be bound to the web response body and change the return type to String

Spring configuration - mvc:annotation-driven, AnnotationMethodHandlerAdapter, and JSON

Thanks in advance any help.
I'm trying to get one of my controller methods to return JSON. Starting off with a simple test:
#RequestMapping(value="/myReqPath", method=RequestMethod.GET)
#ResponseBody
public Map<String, String> myJsonMethod() {
Map<String, String> response = new TreeMap<String, String>();
response.put("test", "test");
return response;
}
It's my understanding that I need <mvc:annotation-driven/> added to my servlet context to accomplish this. The problem is when I add it, it breaks my custom AnnotationMethodHandlerAdapter.
[B]How do I extract and add the needed parts of <mvc:annotation-driven/> to return JSON from the controller?[/B]
Here are the pertinent parts of my servlet config:
<!--Skipping this for now...
<mvc:annotation-driven/>
-->
<!-- JSON Marshaling -->
<util:constant id="jsonBasicClassIntrospector"
static-field="org.codehaus.jackson.map.introspect.BasicClassIntrospector.instance" />
<bean id="jsonJaxbAnnotationIntrospector"
class="org.codehaus.jackson.xc.JaxbAnnotationIntrospector" />
<bean id="jsonVisibilityChecker"
class="org.codehaus.jackson.map.introspect.VisibilityChecker.Std"
factory-method="defaultInstance" />
<bean id="jsonDefaultTypeFactory"
class="org.codehaus.jackson.map.type.TypeFactory"
factory-method="defaultInstance" />
<bean id="jsonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper">
<property name="serializationConfig">
<bean class="org.codehaus.jackson.map.SerializationConfig">
<constructor-arg ref="jsonBasicClassIntrospector" />
<constructor-arg ref="jsonJaxbAnnotationIntrospector" />
<constructor-arg ref="jsonVisibilityChecker" />
<constructor-arg><null/></constructor-arg>
<constructor-arg><null/></constructor-arg>
<constructor-arg ref="jsonDefaultTypeFactory" />
<constructor-arg><null/></constructor-arg>
</bean>
</property>
<property name="deserializationConfig">
<bean class="org.codehaus.jackson.map.DeserializationConfig">
<constructor-arg ref="jsonBasicClassIntrospector" />
<constructor-arg ref="jsonJaxbAnnotationIntrospector" />
<constructor-arg ref="jsonVisibilityChecker" />
<constructor-arg><null/></constructor-arg>
<constructor-arg><null/></constructor-arg>
<constructor-arg ref="jsonDefaultTypeFactory" />
<constructor-arg><null/></constructor-arg>
</bean>
</property>
</bean>
...
<!-- My custom AnnotationMethodHandlerAdapter... -->
<bean id="sessionArgResolver" class="com.SessionParamArgumentResolver"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="customArgumentResolver" ref="sessionArgResolver"/>
</bean>
As it stands, my controller method is invoked however, the browser returns http status 406:
406 Not Acceptable - [url]http://localhost:8080/myApp/myReqPath[/url]
If you already have a custom AnnotationMethodHandlerAdapter declaration, you can just add a list of HttpMessageConverters to it:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="customArgumentResolver" ref="sessionArgResolver"/>
<property name = "messageConverters">
<list>
<bean
class = "org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name = "objectMapper" ref = "jsonObjectMapper" />
</bean>
</list>
</property>
</bean>

configuring the jacksonObjectMapper not working in spring mvc 3

What I am aiming to do is to configure spring mvc 3 to not return “null” object in json response.
I've asked the question how to configure spring mvc 3 to not return "null" object in json response? . And the suggestion I got is to configure the ObjectMapper, setting the serialization inclusion to JsonSerialize.Inclusion.NON_NULL. So Based on Spring configure #ResponseBody JSON format, I did the following changes in spring config file. But I got the error "Rejected bean name 'jacksonObjectMapper': no URL paths identified org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping:86-AbstractDetectingUrlHandlerMapping.java" during app startup.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- Configures the #Controller programming model -->
<mvc:annotation-driven />
<!-- Forwards requests to the "/" resource to the "welcome" view -->
<!--<mvc:view-controller path="/" view-name="welcome"/>-->
<!-- Configures Handler Interceptors -->
<mvc:interceptors>
<!-- Changes the locale when a 'locale' request parameter is sent; e.g. /?locale=de -->
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
</mvc:interceptors>
<!-- Saves a locale change using a cookie -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver" />
<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="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_DEFAULT</value>
</list>
</property>
</bean>
<!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
I have no idea why it's been rejected. Any suggestion is greatly appreciated!
<mvc:annotation-driven /> and AnnotationMethodHandlerAdapter cannot be used together. (ref: spring forum thread). Possible solution
do not use <mvc:annotation-driven/>. Declaring bean: DefaultAnnotationHandlerMapping
and AnnotationMethodHandlerAdapter and other settings like validation, formatting.
use spring 3.1, which has <mvc:message-converters> (ref: Spring jira)