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.
The Spring Web MVC framework provides Model-View-Controller (MVC) architecture and ready components that can be used to develop flexible and loosely coupled web applications.
Make an ajax call using the url defined in the form's th:action. Serialize the form data. Your controller will be able to recieve this in an object. Replace the part of your html code with the returned fragment.
See here and here. JQuery.serialize() isn't going to convert the form to JSON for you. It will only create a query string out of it.
You may also need to change
jq.post("/SpringjQueryTest/dev/main/ajax/bean", number,
function(data) {
alert("Added Number below the button");
alert(data);
});
to
jq.ajax({type: 'POST', url: '/SpringjQueryTest/dev/main/ajax/bean', data: number, contentType: 'application/json',
success: function(data) {
alert("Added Number below the button");
alert(data);
}});
So that the correct Content-Type
is sent and Spring can properly decode it.
If you aren't explicitly trying to use JSON, forgo using @RequestBody
and follow the example here that simply binds the form values to the bean.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With