Konstantin B.
Konstantin B.

Reputation: 485

Spring MVC @RequestBody JSON

I'm getting an error that the request sent by the client was syntactically incorrect. What is being done wrong? Here is my code:

@Entity
@Table(name = "display")
public class Display  {
   private String diagonal;
   private String aspectRatio;
  //getter and setter
}



  $.ajax({
            type:'POST',
            url:'/admin/updateDisplay',
            data:{'diagonal':"sss"}
        })



@Controller
@RequestMapping(value = "/admin")
public class AdminController {

   @RequestMapping(value = "/updateDisplay", method = RequestMethod.POST)
   public String updateDisplay(@RequestBody Display display){

      System.out.print(display);
      return null;
   }

}

Upvotes: 4

Views: 55049

Answers (5)

BurnetZhong
BurnetZhong

Reputation: 448

You must convert the JSON data to string before pass it to Spring MVC. So, here is the solution in your case:

$.ajax({
   type:'POST',
   url:'/admin/updateDisplay',
   data: JSON.stringify({'diagonal':"sss"})
})

Upvotes: 1

Mike Rocke
Mike Rocke

Reputation: 610

I think you need to say what the service media type will consume for Spring to know how to unmarshall it. Probably application/json.

@RequestMapping(value = "/updateDisplay", method = {RequestMethod.POST}, 
consumes = {"application/json"})

Probably some Json library too, like Jackson.

Upvotes: 3

Daniela Morais
Daniela Morais

Reputation: 2237

I don't know if this is your problem too, but with me the value is wrong and caused a error 405, example:

@RequestMapping(value = "/planilha/{id}", method = RequestMethod.PUT)
    public String update(@PathVariable("id") String id, @RequestBody String jsonStr) {
        BasicDBObject json = ((BasicDBObject) JSON.parse(jsonStr));
        PlanilhaDAO dao = new PlanilhaDAO();
        BasicDBObject ola = dao.update(id, json);

        return ola.toString();
    }

    @RequestMapping(value = "/planilha/{id}", method = RequestMethod.DELETE)
    public String delete(@PathVariable("id") String id) {
        PlanilhaDAO dao = new PlanilhaDAO();
        BasicDBObject temp = dao.remove(id);

        return temp.toString();
    }

Needed the change for:

@RequestMapping(value = "/planilha/{id}/**", method = RequestMethod.PUT)
    public String update(@PathVariable("id") String id, @RequestBody String jsonStr) {
        BasicDBObject json = ((BasicDBObject) JSON.parse(jsonStr));
        PlanilhaDAO dao = new PlanilhaDAO();
        BasicDBObject ola = dao.update(id, json);

        return ola.toString();
    }

    @RequestMapping(value = "/planilha/{id}", method = RequestMethod.DELETE)
    public String delete(@PathVariable("id") String id) {
        PlanilhaDAO dao = new PlanilhaDAO();
        BasicDBObject temp = dao.remove(id);

        return temp.toString();
    }

Upvotes: 0

dharam
dharam

Reputation: 8096

Use the following:

$.ajax({
        type:'POST',
        url:'/admin/updateDisplay',
        data:{"diagonal":"sss","aspectRatio":"0.5"},
        contentType: 'application/json',
        dataType: 'json',
    })

it works.

EDIT

If you are booting up Spring application Context using annotaitons, then your config class must have:

@Override
protected void configureContentNegotiation(
        ContentNegotiationConfigurer configurer) {
    configurer.favorPathExtension(false).favorParameter(true)
            .parameterName("mediaType").ignoreAcceptHeader(true)
            .useJaf(false).defaultContentType(MediaType.APPLICATION_JSON)
            .mediaType("xml", MediaType.APPLICATION_XML)
            .mediaType("json", MediaType.APPLICATION_JSON);
}

And your ajax request must include

contentType: 'application/json',
dataType: 'json',

check the modified ajax call above.

If you are booting up spring application context using XMLs then use the below:

<bean id="contentNegotiationManager"
         class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false" />
    <property name="favorParameter" value="true" />
    <property name="parameterName" value="mediaType" />
    <property name="ignoreAcceptHeader" value="true"/>
    <property name="useJaf" value="false"/>
    <property name="defaultContentType" value="application/json" />

    <property name="mediaTypes">
        <map>
            <entry key="json" value="application/json" />
            <entry key="xml" value="application/xml" />
       </map>
    </property>
</bean>

For more details on writing RESTFUL webservices with Spring 3.2 see my blog

Upvotes: 3

a better oliver
a better oliver

Reputation: 26828

You don't need @RequestBody.

With @RequestBody Spring calls a converter that takes the whole request and converts it to an object of the required type. You send your data as application/x-www-form-urlencoded, which is the default of jQuery, and there is no built-in converter for that.

Without @RequestBody, when you send form data, spring creates an empty object and sets the properties based on the data you sent. So in your case Spring would do something like

display = new Display();
display.setDiagonal("sss");

Which, I guess, is what you want.

Upvotes: 0

Related Questions