Spring 3 Type Conversion Errors - spring-mvc

I have been trying out the new Spring MVC 3.0 Type Conversion Framework. I cannot find out how to trap conversion errors.
I am using the new mvc schema:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- Scan this package and sub-packages for Annotated Controllers -->
<context:component-scan base-package="springmvc.simple"/>
<!-- New Spring 3.0 tag to enable new Converter and Formatting Frameworks -->
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
And a simple command class:
public class Amount {
#NumberFormat(style=Style.CURRENCY)
#Min(0)
private BigDecimal amount = BigDecimal.valueOf(10000, 2);
#DateTimeFormat(iso=ISO.DATE)
private Date date = new Date();
public Date getDate() {
return date;
}
public BigDecimal getAmount() {
return amount;
}
}
And an equally simple controller:
#Controller
#RequestMapping(value="/addVat.html")
public class AddVatController {
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.initDirectFieldAccess();
}
#RequestMapping(method = RequestMethod.GET)
public String setupForm(Model model) {
model.addAttribute("commandBean", new Amount());
return "addVatForm";
}
#RequestMapping(method = RequestMethod.POST)
public String onSubmit(#ModelAttribute("commandBean") #Valid Amount commandBean, BindingResult amountBinding, Model model) {
if (amountBinding.hasErrors()) {
return "addVatForm";
}
BigDecimal result = commandBean.getAmount().multiply(new BigDecimal("1.175"));
model.addAttribute("result", result);
return "result";
}
}
This works fine - I get validation error in my result.jsp if I enter a negative value for the BigDecimal. However if I try to send a Date such as 2010-07-024, which does not conform to ####-##-##, I get an error:
org.springframework.core.convert.ConversionFailedException: Unable to convert value 2010-07-024 from type 'java.lang.String' to type 'java.util.Date'; nested exception is org.springframework.core.convert.ConversionFailedException: Unable to convert value 2010-07-024 from type 'java.lang.String' to type 'java.util.Date'; nested exception is java.lang.IllegalArgumentException: Invalid format: "2010-07-024" is malformed at "4"
org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:40)
org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:135)
org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:199)
org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:169)
org.springframework.beans.DirectFieldAccessor.setPropertyValue(DirectFieldAccessor.java:125)
org.springframework.beans.AbstractPropertyAccessor.setPropertyValue(AbstractPropertyAccessor.java:50)
org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:76)
org.springframework.validation.DataBinder.applyPropertyValues(DataBinder.java:665)
org.springframework.validation.DataBinder.doBind(DataBinder.java:561)
org.springframework.web.bind.WebDataBinder.doBind(WebDataBinder.java:190)
org.springframework.web.bind.ServletRequestDataBinder.bind(ServletRequestDataBinder.java:110)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.doBind(AnnotationMethodHandlerAdapter.java:696)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doBind(HandlerMethodInvoker.java:744)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:296)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:163)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:414)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:402)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:563)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
Which is fine - but how do I trap the error? I was expecting BindingResult to simply contain another error?

See if registering appropriate DateEditor can help you..... 15.3.2.12
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.initDirectFieldAccess();
**/* register appropriate date editor */**
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}

According to Juergen Hoeller, this was fixed in Spring 3.0.2

Related

"HTTP Status 404" and there is an extra "wrong path" in request path

This is my practice Spring project. I can not redirect to the right page in SpringMVC Interceptor.
spring-mvc.xml
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<description>Spring MVC Configuration</description>
<context:property-placeholder ignore-unresolvable="true" location="classpath:myshop.properties"/>
<context:component-scan base-package="com.huahua.my.shop" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="${web.view.prefix}"/>
<property name="suffix" value="${web.view.suffix}"/>
</bean>
<mvc:resources mapping="/**/static/**" location="/static/" cache-period="31536000"/>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/login"/>
<mvc:exclude-mapping path="/static/**"/>
<mvc:exclude-mapping path="/loginOut"/>
<bean class="com.huahua.my.shop.web.admin.web.intercepter.LoginIntercepter" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/login"/>
<bean class="com.huahua.my.shop.web.admin.web.intercepter.PermissionIntercepter" />
</mvc:interceptor>
</mvc:interceptors>
</beans>
this is UserController class
#Controller
#RequestMapping(value = "/user")
public class UserController {
#Autowired
TbUserService tbUserService ;
#RequestMapping(value = "/list" , method = RequestMethod.GET)
public String userList(){
return "user_list" ;
}
}
this is my interceptor
public class LoginIntercepter implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o ) throws Exception {
TbUser tbUser =(TbUser) httpServletRequest.getSession().getAttribute(ConstantUtils.SESSION_USER); //SESSION_USER = user
System.out.println(httpServletRequest.getRequestURL());
if (tbUser == null){
httpServletResponse.sendRedirect("login");
}
return true;
}
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {}
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {}
}
this is LoginController
#Controller
public class LoginController {
#Autowired
private TbUserService tbuserService ;
#RequestMapping(value = {"","login"},method = RequestMethod.GET)
public String login(){
return "login" ;
}
#RequestMapping(value = "login",method = RequestMethod.POST)
public String login(#RequestParam(required = true) String email ,
#RequestParam(required = true ) String password ,
#RequestParam(required = false) String isRemember,
HttpServletRequest request,
Model model){
TbUser user = tbuserService.loginRight(email, password);
isRemember = isRemember == "on" ? "checked" : null ;
if (user != null ){
request.getSession().setAttribute(ConstantUtils.SESSION_USER,user);
request.getSession().setAttribute("remember",isRemember);
return "redirect:/main" ;
}
else {
model.addAttribute("message","username or password is wrong");
return "login" ;
}
}
when I log in and request http://localhost:8080/user/list , I successfully entered user_list.jsp.
after a time, this session is out of time,I refresh this page,
the HTTP of refresh user_list page
I hope it is redirected to http://localhost:8080/login,
but I got this path http://localhost:8080/user/login
wrong with 404
how can I solve this wrong?
why there is extra a '/user' in the path?
and what are the relation between the /user in redirect path and the #RequestMapping(value = "/user") in UserController ?
Thank you very much!!!
As the API docs note for HttpServletResponse#sendRedirect:
Sends a temporary redirect response to the client using the specified
redirect location URL and clears the buffer. The buffer will be
replaced with the data set by this method. Calling this method sets
the status code to SC_FOUND 302 (Found). This method can accept
relative URLs;the servlet container must convert the relative URL to
an absolute URL before sending the response to the client. If the
location is relative without a leading '/' the container interprets it
as relative to the current request URI. If the location is relative
with a leading '/' the container interprets it as relative to the
servlet container root.
So because you have specified a relative URL is resolved relative to the current request URl /users/list
So you need to change it to:
httpServletResponse.sendRedirect("/login");

Aspectj advice not getting executed

I am trying to code a simple AspectJ implementation but the Advice is not getting executed.
The LoggingAspect Class is getting initiated as in the console I can see s.o.p of constructor
This is logging aspect
getting printed when the ApplicationContext is loaded and controllerAspect is initialized. When I run the main method , the output is
Name: John Age :12
What I was expecting was the s.o.p for #Before advice should be printed first and then for getter methods #AfterReturning s.o.p should be printed.
There is no compilation error , the program is running but advice is not getting executed.
According to the pointcut, the advice should get implemented on all methods of the Customer class.
I went through some of the similar problems posted here , but could not figure out what was the issue with my implementation.
Can any one figure the mistake I am making and provide the resolution ?
Here is the snippet servlet-context.xml
<context:component-scan base-package="main.com.controller"/>
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven></annotation-driven>
<aop:aspectj-autoproxy/>
<!-- AOP support -->
<bean id='controllerAspect' class='main.com.logging.LoggingAspect' />
<beans:bean id="cust" class="main.com.dtos.Customer"</beans:bean>
<resources mapping="/resources/**" location="/resources/" />
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/"/>
<beans:property name="suffix" value=".jsp"/>
</beans:bean>
The LoggingAspect class is :
#Aspect
public class LoggingAspect {
public LoggingAspect() {
System.out.println("This is logging aspect");
}
#Pointcut("execution(* com.dtos.*.*(..))")
public void getMethodPointcut() {}
#AfterReturning(pointcut = "getMethodPointcut()", returning="retVal")
public void afterReturningAdvice(Object retVal) {
System.out.println("Returning:" + retVal.toString() );
}
#Before("getMethodPointcut()")
public void printBefore(JoinPoint jp ) {
System.out.println("Before calling method:"+jp.getSignature());
}
Customer class is :
#Size(max=30, min=3)
#NotNull
private String name;
#Max(150)
#NotNull
private String age;
public Customer() {}
public Customer(String sName, String sAge) {
name = sName;
age = sAge;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
#Override
public String toString() {
return "Customer [name=" + name + ", age=" + age + "]";
}
Main method is :
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("classpath:servlet- context.xml");
Customer cust = (Customer)context.getBean("cust");
cust.setAge("12");
cust.setName("John");
String name = cust.getName();
String age = cust.getAge();
System.out.println("Name: "+name+" Age :"+age);
}
Aspectj POM dependencies
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.4</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.4</version>
</dependency>
Just so as to enable you to close the question by accepting an answer, I am repeating my answer from the comment:
Your Spring config implies it is main.com.dtos.Customer, your aspect pointcut is looking for com.dtos.* (without main. prefix) though.

MockMVC Integrate test controller with session scoped bean

I am trying to integrate test a Spring Controller method that uses a spring session scoped bean which is injected into the controller. In order for my test to pass I must be able to access my session bean to set some values on it before I make my mock call to this controller method. Issue is a new session bean is created when I make the call instead of using the one I pulled of the mock application context. How can I make my controller use the same UserSession bean?
Here is my test case
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration("src/main/webapp")
#ContextConfiguration({"file:src/main/webapp/WEB-INF/applicationContext.xml",
"file:src/main/webapp/WEB-INF/rest-servlet.xml",
"file:src/main/webapp/WEB-INF/servlet-context.xml"})
public class RoleControllerIntegrationTest {
#Autowired
private WebApplicationContext wac;
protected MockMvc mockMvc;
protected MockHttpSession mockSession;
#BeforeClass
public static void setupClass(){
System.setProperty("runtime.environment","TEST");
System.setProperty("com.example.UseSharedLocal","true");
System.setProperty("com.example.OverridePath","src\\test\\resources\\properties");
System.setProperty("JBHSECUREDIR","C:\\ProgramData\\JBHSecure");
}
#Before
public void setup(){
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
mockSession = new MockHttpSession(wac.getServletContext(), UUID.randomUUID().toString());
mockSession.setAttribute("jbhSecurityUserId", "TESTUSER");
}
#Test
public void testSaveUserRole() throws Exception {
UserSession userSession = wac.getBean(UserSession.class);
userSession.setUserType(UserType.EMPLOYEE);
userSession.setAuthorizationLevel(3);
Role saveRole = RoleBuilder.buildDefaultRole();
Gson gson = new Gson();
String json = gson.toJson(saveRole);
MvcResult result = this.mockMvc.perform(
post("/role/save")
.contentType(MediaType.APPLICATION_JSON)
.content(json)
.session(mockSession))
.andExpect(status().isOk())
.andReturn();
MockHttpServletResponse response = result.getResponse();
}
Here is my controller method I am needing tested
#Resource(name="userSession")
private UserSession userSession;
#RequestMapping(method = RequestMethod.POST, value = "/save")
public #ResponseBody ServiceResponse<Role> saveRole(#RequestBody Role role,HttpSession session){
if(userSession.isEmployee() && userSession.getAuthorizationLevel() >= 3){
try {
RoleDTO savedRole = roleService.saveRole(role,ComFunc.getUserId(session));
CompanyDTO company = userSession.getCurrentCompany();
It is not passing this line because the UserSession Object is not the same
if(userSession.isEmployee() && userSession.getAuthorizationLevel() >= 3){
This is the declaration of my user session bean.
#Component("userSession")
#Scope(value="session",proxyMode= ScopedProxyMode.INTERFACES)
public class UserSessionImpl implements UserSession, Serializable {
private static final long serialVersionUID = 1L;
Both controlle and bean are created using component scan in my applicationContext.xml
<context:annotation-config />
<!-- Activates various annotations to be detected in bean classes -->
<context:component-scan
base-package="
com.example.app.externalusersecurity.bean,
com.example.app.externalusersecurity.service,
com.example.app.externalusersecurity.wsc"/>
<mvc:annotation-driven />
Add the following bean configuration, which adds a session context for each thread
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="session">
<bean class="org.springframework.context.support.SimpleThreadScope"/>
</entry>
</map>
</property>
</bean>
An equivalent in Java's configuration class would the following bean declaration
#Bean
public CustomScopeConfigurer scopeConfigurer() {
CustomScopeConfigurer configurer = new CustomScopeConfigurer();
Map<String, Object> workflowScope = new HashMap<String, Object>();
workflowScope.put("session", new SimpleThreadScope());
configurer.setScopes(workflowScope);
return configurer;
}
For more details, see
http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes-custom-using
Using different Bean definition profiles for test and production worked for me - here's how a XML based setup could look like:
<beans profile="production">
<bean id="userSession" class="UserSessionImpl" scope="session" >
<aop:scoped-proxy/>
</bean>
</beans>
<beans profile="test">
<bean id="userSession" class="UserSessionImpl" >
</bean>
</beans>
To use the test profile for your test, add #ActiveProfiles to your test class:
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration("src/main/webapp")
#ContextConfiguration({"file:src/main/webapp/WEB-INF/applicationContext.xml",
"file:src/main/webapp/WEB-INF/rest-servlet.xml",
"file:src/main/webapp/WEB-INF/servlet-context.xml"})
#ActiveProfiles(profiles = {"test"})
public class RoleControllerIntegrationTest {
[...]

Issue on implementing jdbc dao support in spring application

I was trying to access database using jdbcdao as per the following example:
http://www.mkyong.com/spring/spring-jdbctemplate-jdbcdaosupport-examples/
userdao, userdaoimpl,daocontext and datacontext.xml are as follows:
DAOIMPL
public class UserDAOImpl extends JdbcDaoSupport implements UserDAO {
/*Creates User */
public void insertUser(User user){
String sql = "INSERT INTO Users " +
"(id, username, password,role) VALUES (?, ?, ?,?)";
getJdbcTemplate().update(sql, new Object[] { user.getUserId(),
user.getUserName(),user.getPassWord()
});
}
}
DAO
import java.util.List;
import spring.web.models.User;
public interface UserDAO {
public void insertUser(User user);
}
DAOCONTEXT.XML
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<bean id="userDAO" class="spring.web.dao.impl.UserDAOImpl">
<property name="primaryDataSource" ref="oracleDataSource" />
</bean>
</beans>
DATA-CONTEXT.XML
<?xml version="1.0"?>
<beans
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans">
<bean id="oracleDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property value="oracle.jdbc.OracleDriver" name="driverClassName" />
<property value="jdbc:oracle:thin:#192.168.72.68:1521:d2he"
name="url" />
<property value="aaryal_1" name="username" />
<property value="oracle" name="password" />
</bean>
</beans>
The error I am facing is as follows:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDAO' defined in class path resource [dao-context.xml]:
Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException:
Invalid property 'primaryDataSource' of bean class [spring.web.dao.impl.UserDAOImpl]:
Bean property 'primaryDataSource' is not writable or has an invalid setter method.
Does the parameter type of the setter match the return type of the getter?
Please suggest me what did I miss.
You need a setPrimaryDataSource method in UserDAOImpl class. The error says it all. It's expecting a property called primaryDataSource in your class, but can't find it. Hence the error.
You'll need to do this:
private DataSource dataSource;
public void setPrimaryDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
EDIT:
If you go through the API of JdbcDaoSupport, the setDataSource method already exists. So to solve your error, you can either do the above, or simply rename your DataSource bean name to dataSource

RestTemplate POST with JSon

once again iam looking a for help/guide from experts,
My problem is, i need to create Dynamic web site which calls to restfull server to get data, all the requests are POST and returns json object. Iam thinking of use of Spring RestTemplate to make calls to server. My Server works ok, meaning currently some android and Apple apps connects to same APIs and they work ok. But when i try to use RestTemplate to connect to server, it gives some errors
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
this is my server,
#Controller
public class ABCController
{
#RequestMapping(method = RequestMethod.POST, value = "/user/authenticate")
public #ResponseBody LoginResponse login(#RequestParam("email") String email,#RequestParam("password") String password,#RequestParam("facebookId") String facebookId) {
LoginRequest request = new LoginRequest(email, password, facebookId);
UserBusiness userBusiness = UserBusinessImpl.getInstance();
return userBusiness.login(request);
}
}
And this is my spring configs of server,
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean id="jsonViewResolver" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonConverter" />
</list>
</property>
</bean>
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
</bean>
<bean name="abcController" class="com.abc.def.controller.ABCController" />
<mvc:annotation-driven />
</beans>
This is how i try to call the server using RestTemplate,
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<!-- <constructor-arg ref="httpClientFactory"/> -->
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper">
<ref bean="JacksonObjectMapper" />
</property>
</bean>
</list>
</property>
</bean>
<bean id="JacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" />
and this is how i use it (for testing)
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("root-context.xml");
RestTemplate twitter = applicationContext.getBean("restTemplate", RestTemplate.class);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("email", "x1#test.com");
map.add("password", "abc");
map.add("facebookId", null);
HttpEntity<LoginResponse> response= twitter.exchange("https://abc.com/Rest/api/user/authenticate", HttpMethod.POST, map, LoginResponse.class);
my login response class, and its sub classes,
LoginResponse
public class LoginResponse extends BaseResponse {
private LoginBase data;
with getters and setters
}
Login Base
public class LoginBase {
private String token;
private User user;
with getters and setters
}
User
public class User {
private Integer userId;
private String email;
private Integer status;
private String name;
with getters and setters
}
finally BaseResponse
public class BaseResponse {
protected String statusCode;
with getter and setter }
My questions are,
1. Why do i get this error when i call the server
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#63de8f2d: defining beans [restTemplate,JacksonObjectMapper]; root of factory hierarchy
WARN : org.springframework.web.client.RestTemplate - POST request for "https://abc.com/Rest/api/user/authenticate" resulted in 400 (Bad Request); invoking error handler
Exception in thread "main" org.springframework.web.client.HttpClientErrorException: 400 Bad Request
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:90)
at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:494)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:451)
2. how do i map json response to java LoginResponse
You might have to add the content-type and accept headers to your request.
Mapping the response to LoginResponse can be done directly like this
LoginResponse lResponse = response.getBody();
or If you are using restTemplate.postForObject(), the reponse will be in the form of LoginResponse

Resources