Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery and Spring MVC

Tags:

java

jquery

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.

like image 295
Neel Avatar asked Jul 19 '11 13:07

Neel


People also ask

What is Spring Web MVC?

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.

How do I use Ajax in Thymeleaf?

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.


1 Answers

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.

like image 133
laz Avatar answered Sep 28 '22 23:09

laz