2

I'm trying to use Spring MVC with JSON. It works great when a return an object from the controller, but when I try to make an AJAX call passing a custom object as parameter I'm getting HTTP 415 error.

My spring-servlet.xml:

<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:p="http://www.springframework.org/schema/p"
    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/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <tx:annotation-driven /> 
   <context:annotation-config/>
    <context:component-scan
        base-package="com.sommer.controller" />
        <tx:annotation-driven transaction-manager="transactionManager"/>

    <context:component-scan base-package="com.sommer.service" />

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/view/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <bean id="messageSource"
    class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="classpath:messages" />
        <property name="defaultEncoding" value="UTF-8"/>
    </bean>


 <!-- ========= [ADDED FOR JSON SUPPORT] ========= -->
    <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 id="localeChangeInterceptor"
        class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
        <property name="paramName" value="lang" />
    </bean>

    <bean id="localeResolver"
        class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
        <property name="defaultLocale" value="es"/>
    </bean>

    <bean id="handlerMapping"
        class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="interceptors">
            <ref bean="localeChangeInterceptor" />
        </property>
    </bean>


    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
      <property name="url" value="jdbc:mysql://localhost:3306/sommer"/>
      <property name="username"  value="root"/>
      <property name="password" value="master"/>
    </bean>

    <bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
    p:dataSource-ref="dataSource"
    p:jpaVendorAdapter-ref="jpaAdapter">
        <property name="loadTimeWeaver">
                <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
        </property>                             
        <property name="persistenceUnitName" value="sommerPersistenceUnit"></property>
    </bean>

     <bean id="jpaAdapter"
    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
    p:database="MYSQL"
    p:showSql="true"
    p:generateDdl="true"/>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
    p:entityManagerFactory-ref="entityManagerFactory"/>

    <tx:annotation-driven transaction-manager="transactionManager"/>



</beans>

My controller:

@RequestMapping(value="/editJSON2",headers={"content-type=application/json,application/xml,application/x-www-form-urlencoded"})
    public @ResponseBody ActionResult editJSON2(@RequestBody CustomerTO toEdit){
        return new ActionResult(toEdit);
    }

Classes:

public class ActionResult {
    private Boolean success;
    private String message;
    private Object object;

    public ActionResult(){
        this.success = true;
        this.object = null;
        this.message = null;
    }

    public ActionResult(Boolean isSuccess,Object obj, String message){
        this.success = isSuccess;
        this.object = obj;
        this.message = message;
    }

    public ActionResult(Object obj){
        this.success = true;
        this.object = obj;
        this.message = "";
    }

    public ActionResult(String message){
        this.success = false;
        this.object = null;
        this.message = message;
    }

    public void setError(String msg){
        this.success = false;
        this.message = msg;
    }

    public Boolean getSuccess() {
        return success;
    }
    public void setSuccess(Boolean success) {
        this.success = success;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public Object getObject() {
        return object;
    }
    public void setObject(Object object) {
        this.object = object;
    }
}


public class CustomerTO {

    private Long id;
    private String name;
    private String email;

    private TestObject[] items;

    public TestObject[] getItems() {
        return items;
    }

    public void setItems(TestObject[] items) {
        this.items = items;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public DocumentType getDocumentType() {
        return documentType;
    }

    public void setDocumentType(DocumentType documentType) {
        this.documentType = documentType;
    }

    public String getDocumentNumber() {
        return documentNumber;
    }

    public void setDocumentNumber(String documentNumber) {
        this.documentNumber = documentNumber;
    }

    private String surname;
    private String sex;
    private DocumentType documentType;
    private String documentNumber;

    public CustomerTO() {
    }

    public CustomerTO(Customer customer) {
        this.id = customer.getId();
        this.documentNumber = customer.getDocumentNumber();
        this.documentType = customer.getDocumentType();
        this.name = customer.getName();
        this.surname = customer.getSurname();
        this.sex = Sex.MALE.equals(customer.getSex())?"M":"F";
        this.email = customer.getEmail();
        this.items = new TestObject[1];
        TestObject tio = new TestObject();
        tio.setText("ITEM !");
        this.items[0] = tio;
    }

My ajax call:

var currentCustomer = {
            'id': $('#id').val()
            ,'name' :$('#name').val()
            ,'surname' :$('#surname').val()
            ,'documentType' :$('#documentType').val()
            ,'documentNumber' :$('#documentNumber').val()
            ,'sex' :$('#sex').val()
            ,'email' :$('#email').val()
        };


        // Send the request
        $.post('editJSON2.html', {toEdit:currentCustomer}, function(response) {
            alert('OK');
        }, 'json');

The problem I think is here:

public @ResponseBody ActionResult editJSON2(@RequestBody CustomerTO toEdit)

I think @ResquestBody is not working for me. I also have

@RequestMapping("/editJSON")
public @ResponseBody ActionResult editJSON(@RequestParam(required=false) Long customerId){
    CustomerTO toEdit = customerId!=null ? new CustomerTO(customerService.getById(customerId)):new CustomerTO();
    return new ActionResult(toEdit);
}

And when I call it I have no problem.

This is information I collected from firebug:

Parámetrosapplication/x-www-form-urlencoded
toEdit[documentNumber]  36466
toEdit[documentType]    DNI
toEdit[email]   [email protected]
toEdit[id]  2
toEdit[name]    John
toEdit[surname] Doe
Código fuente
toEdit%5Bid%5D=2&toEdit%5Bname%5D=John&toEdit%5Bsurname%5D=Doe&toEdit%5BdocumentType%5D=DNI&toEdit%5BdocumentNumber%5D=36466&toEdit%5Bemail%5D=jpruizmdq%40hotmail.com

2 Answers 2

20

It's no tot working because content type of your request is application/x-www-form-urlencoded and it supposed to be application/json

try to send it with Jquery the following way:

$.ajax({
    type: "POST",
    url: "someurl",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    data: "{id: '" + someId + "'}",
    success: function(json) {

}};
Sign up to request clarification or add additional context in comments.

2 Comments

yeah, don´t worry. stackoverflow makes me wait some hours till i can post my answer.
but contentType: application/json while performing a cors request.how to solve the issue then? @Müsli
0

Thanks! Problem solved. Here is the code

@RequestMapping(value="/editJSON2")
    public @ResponseBody ActionResult editJSON2(@RequestBody CustomerTO toEdit){
        return new ActionResult(toEdit);
    }


ajaxCall('editJSON2.html',JSON.stringify(currentCustomer),function(valor){
            alert('OK');
        });


function ajaxCall(url,data,callback,onError){

    jQuery.ajax({
        url:url
        ,dataType: 'json'
        ,data:data
        ,type: "POST"
        ,contentType: "application/json; charset=utf-8"
        ,success:function(actionResult){
                         -----------
        }
        ,error:function(jqXHR, textStatus, errorThrown){
            ---
        }
    });
}

It was simple! I added contentType: "application/json; charset=utf-8" and i used JSON.stringify(currentCustomer). With that it worked

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.