@RequestBody is always empty in Spring

2019-08-02 02:06发布

问题:

The JSONObject is always coming as empty for the method below.

 @RequestMapping(value = "/package/{id}", method = RequestMethod.PUT)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public SPackage updatePackage(@PathVariable String id, @RequestBody JSONObject   
 sPackage) {
}

and my ajax is like this. I am ways getting the object as empty map on the server side

   var jsonObject= {"customerName":$('#customerName').val()}
     var jsonData = JSON.stringify(jsonObject);  
            $.ajax({ 
                type: "PUT",
                url: "http://localhost:8081/someproj/package/" + $('#id').val(),
                dataType: "json",
                data: jsonData,
                async: false,                                               
                contentType: "application/json; charset=utf-8",
                beforeSend : function() { 
                    openModal();
                },
                success: function(data) { 
                    closeModal();
                $('#success').show();
                 console.log(data);
                }
            }); 

回答1:

I guess spring doesn't know to convert your json to JSONObject, the best thing would be to accept a POJO object which has similar structure to your json,

@RequestMapping(value = "/package/{id}", method = RequestMethod.PUT)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public SPackage updatePackage(@PathVariable String id, @RequestBody YourJsonPOJO   
 sPackage) {
}


回答2:

Are you sure there're no exceptions occurring in your Spring code. When converting from JSON to custom object in Spring, you need to specify a custom class that has same fields & format as the JSON coming in. Otherwise, Spring doesn't know who to convert HTTP POST data into a Java object.

In your case, you could do define a POJO like this:

public class MyRequestObj {
    private String customerName;
    // add more fields for any other keys from JSON
}

And put this in your Controller class:

@RequestMapping(value = "/package/{id}", method = RequestMethod.PUT)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public SPackage updatePackage(@PathVariable String id, @RequestBody MyRequestObj   
 myRequestObj) {
    String customerName = myRequestObj.getCustomerName();
}

Of course, if you only want to pass in the customer name as a String to your Controller, then you could also pass it as query string (append ?customerName=someCustomer) and you can retrieve it in Spring as:

@RequestMapping(value = "/package/{id}", method = RequestMethod.PUT)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public SPackage updatePackage(@PathVariable String id, @RequestParam("customerName") String customerName) {
} 


回答3:

You can use this workaround:

@RequestBody Map<String, String> json

That way you can continue using Jackson HttpMessageConverter and work with custom objects in payload.

You can check extended explanaition why this happens at answer here

@RequestBody gives empty JsonObject when making a POST Request