Actually I am trying to send data from jQuery to Spring controller and in Spring controller I am trying to get that data in a custom bean using @RequestBody
. But I am unable to do so. It's not working. But when I am sending the same data as @RequestParam
it's working fine, but in case of @RequestBody
nothing is happened. I have serialized the html form and posting that data to the controller. I am pasting all the codes. I am using jQuery version jquery-1.6.2.min.js
and below is the list of the jars I am using :
commons-fileupload-1.1.1.jar
commons-io-1.2.jar
commons-logging-1.1.1.jar
hibernate-validator-4.0.2.GA.jar
jackson-all-1.7.6.jar
jackson-mapper-asl-1.5.2.jar
jstl-1.2.jar
log4j-1.2.14.jar
servlet-2.3.jar
slf4j-api-1.5.6.jar
slf4j-log4j12-1.5.6.jar
spring-asm-3.0.5.RELEASE.jar
spring-beans-3.0.5.RELEASE.jar
spring-context-3.0.5.RELEASE.jar
spring-core-3.0.5.RELEASE.jar
spring-expression-3.0.5.RELEASE.jar
spring-tx-2.5.5.jar
spring-web-3.0.5.RELEASE.jar
spring-webmvc-3.0.5.RELEASE.jar
validation-api-1.0.0.GA.jar
Below is the controller code :
package com.devmanuals.tutorial.controller;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.devmanuals.tutorial.service.ArithmeticService;
/**
* Handles and retrieves the main requests
*/
@Controller
@RequestMapping("/main/ajax")
public class AjaxController {
protected static Logger logger = Logger.getLogger("controller");
@Resource(name="springService")
private ArithmeticService springService;
/**
* Handles and retrieves the AJAX Add page
*/
@RequestMapping(value = "/add", method = RequestMethod.GET)
public String getAjaxAddPage() {
System.out.println("Received request to show AJAX, add page");
logger.debug("Received request to show AJAX, add page");
// It resolves the /WEB-INF/jsp/ajax-add-page.jsp
return "ajax-add-page";
}
/**
* Handles request for adding two numbers
*/
/**
* Handles request for adding two numbers
*/
@RequestMapping(value = "/add", method = RequestMethod.POST)
public @ResponseBody Integer create(@RequestParam(value="inputNumber1", required=true) Integer inputNumber1,
@RequestParam(value="inputNumber2", required=true) Integer inputNumber2,
Model model) {
logger.debug("Received request to add two numbers");
Integer sum = springService.add(inputNumber1, inputNumber2);
logger.debug("Result is ........" +sum);
return sum;
}
@RequestMapping(method=RequestMethod.POST, value = "/bean")
public @ResponseBody Integer create(@RequestBody NumberBean account, HttpServletResponse response,ModelMap model) {
System.out.println("Test...........");
if (account==null) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return 1;
} else {
return 20;
}
}
/**
* Handles request for adding two numbers
*/
/* @RequestMapping(value = "/add", method = RequestMethod.POST)
public @ResponseBody Integer add(@RequestBody NumberBean number,
Model model) {
//logger.debug("Received request to add two numbers");
System.out.println(number);
Integer sum = springService.add(number.getInputNumber1(), number.getInputNumber2());
return sum;
}*/
}
And the jsp is as below:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript"
src="/SpringjQueryTest/jquery/jquery-1.6.2.min.js"></script>
<script type="text/javascript">
var jq = jQuery.noConflict();
</script>
</head>
<body>
<center>
<h3>Enter Two Numbers for Addition:</h3>
<form id="test">
<table border="1" height="10%" width="10%">
<tr><td><table border="0" height="100%" width="100%">
<tr>
<td><input id="x" type="text" size="5" name="inputNumber1"></td>
<td>+</td>
<td><input id="y" type="text" size="5" name="inputNumber2"></td>
</tr>
<tr>
<td colspan="3" align="center"><input type="submit" value=" Submit "
onclick=add(); /></td>
</tr>
</table>
</td></tr></table>
</form>
<script type="text/javascript">
function add() {
jq(function() {
var number = jq('form').serialize();
alert(number);
jq.post("/SpringjQueryTest/dev/main/ajax/bean", number,
function(data) {
alert("Added Number below the button");
alert(data);
});
});
}
</script>
</center>
</body>
</html>
And here is the applicationContext.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-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">
<!-- Activates various annotations to be detected in bean classes -->
<context:annotation-config />
<!-- Scans the classpath for annotated components that will be auto-registered as Spring beans.
For example @Controller and @Service. Make sure to set the correct base-package-->
<context:component-scan base-package="com.devmanuals.tutorial" />
<!-- Configures the annotation-driven Spring MVC Controller programming model.
Note that, with Spring 3.0, this tag works in Servlet MVC only! -->
<mvc:annotation-driven />
</beans>
And here is spring-servlet.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:tx="http://www.springframework.org/schema/tx"
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/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<bean id="jacksonMessageConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jacksonMessageConverter" />
</list>
</property>
</bean>
<!-- Declare a view resolver -->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
Here is the NumberBean.java
package com.devmanuals.tutorial.controller;
import java.io.Serializable;
public class NumberBean implements Serializable{
private int inputNumber1;
private int inputNumber2;
public int getInputNumber1() {
return inputNumber1;
}
public void setInputNumber1(int inputNumber1) {
this.inputNumber1 = inputNumber1;
}
public int getInputNumber2() {
return inputNumber2;
}
public void setInputNumber2(int inputNumber2) {
this.inputNumber2 = inputNumber2;
}
@Override
public String toString() {
return "NumberBean [inputNumber1=" + inputNumber1 + ", inputNumber2="
+ inputNumber2 + "]";
}
}
And here is the ArithmeticService.java
package com.devmanuals.tutorial.service;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @Service enables the class to be used as a Spring service
* @Transactional enables transaction support for this class
*/
@Service("springService")
@Transactional
public class ArithmeticService {
protected static Logger logger = Logger.getLogger("service");
/**
* Adds two numbers
*/
public Integer add(Integer operand1, Integer operand2) {
logger.debug("Adding two numbers");
return operand1 + operand2;
}
}
Here is my web.xml :
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/dev/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>/WEB-INF/jsp/ajax-add-page.jsp</welcome-file>
</welcome-file-list>
</web-app>
UPDATE :
as per the answers I am converting the serialized form value into json and in controller end I am getting it as a java bean through @RequestBody
. But now the problem is the @ResponseBody
is not working. Within the jq.ajax
function the success callback method is not getting invoked. I am totally confused,as it was successfully working before I tried @RequestBody
,with @RequestParam
. Plz help me.......
the jQuery function :
jq.ajax( {
url : "/SpringjQueryTest/dev/main/ajax/test",
type : "POST",
data : json,
dataType : "json",
contentType : "application/json; charset=utf-8",
success : function(data) {
alert("Added Number below the button");
alert(data);
},
error : function(xhr, desc, err) {
alert("Desc: " + desc + "\nErr:" + err);
}
});
Updated controller method :
/**
* Handles request for adding two numbers
*/
@RequestMapping(value = "/test", method = RequestMethod.POST)
public @ResponseBody
Integer test(@RequestBody NumberBean number,HttpServletResponse response ) {
logger.debug("Received request to add two numbers");
response.setContentType("application/json");
System.out.println(number);
Integer sum = springService.add(number.getInputNumber1(), number.getInputNumber2());
return sum;
}
I am able to see the output
Received request to add two numbers
in my console and even the sum is getting generated. But the success function of jq.ajax
success : function(data) {
alert("Added Number below the button");
alert(data);
}
is not getting invoked. Nothing is happened. Even no error messages.
Also I noticed in the log of HttpTrace tool
that though I am explicitly setting the response content type as application/json
in the controller method but the content type remains text/html
only.
I am just wondering as it was successfully executing when I was using @RequestParam
, but with @RequestBody
is not working.
Please find the applicationContext.xml also
<?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-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">
<!-- Activates various annotations to be detected in bean classes -->
<context:annotation-config />
<!-- Scans the classpath for annotated components that will be auto-registered as Spring beans.
For example @Controller and @Service. Make sure to set the correct base-package-->
<context:component-scan base-package="com.devmanuals.tutorial" />
<!-- Configures the annotation-driven Spring MVC Controller programming model.
Note that, with Spring 3.0, this tag works in Servlet MVC only! -->
<mvc:annotation-driven />
<bean id="jacksonMessageConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jacksonMessageConverter" />
</list>
</property>
</bean>
<bean id="exceptionMessageAdapter"
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver">
<property name="messageConverters">
<list>
<!-- Support JSON -->
<ref bean="jacksonMessageConverter" />
</list>
</property>
</bean>
</beans>
And I do have jackson-all-1.8.3.jar
in my classpath even. I am really confused.