简体   繁体   中英

ajax json Post to Spring mvc Controller “415 Unsupported Media Type”

Hi so I am having problems with getting the JSON from my form to my work with spring mvc. My form is dynamic and the JSON comes back as a list of the criteria that the user filled out on the form. Ideally I would like to be able to get the JSON to come over as a Criterias object which contains a list of Criteria objects. (Like my model classes below) I dont know if this is possible or if there is a different way to go about it but any advice would be much appreciated.

**Currently I am receiving a 415 unsupported Media Type from the ajax post.

CONTROLLER

@RestController   
public class Controller {
@RequestMapping(value-"/test",method=RequestMethod.GET
public ModelAndView getTest(){

ModelAndView model = new ModelAndView("test");

}
@RequestMapping(value-"/query",method=RequestMethod.POST
public ModelAndView submitTest(@RequestBody Criterias criterias){

//do stuff....
ModelAndView model = new ModelAndView("results");

}

MODEL

public class Criterias{
private List<Criteria> criteria = new ArrayList<Criteria>();
getter setter...
}

public class Criteria{
private String field;
private String filter;
private String operator;
private String criteria;


getters setters...
}

TEST.JSP

 $(document).ready(function() { $("#theButton").click(function() { $('#myTable').append("<tr><td><select name = 'operator'><option>AND</option><option>OR</option></select></td><td>Field:<select name='field'><option>a</option><option>b</option> <option>c</option> <option>d</option> </select> </td> <td> <select name='filter'> <option>Contains</option> <option>Does Not Contain</option> <option>Equals</option> <option>Does Not Equal</option> </select> </td><td> <input name='criteria' type='text'> </td><td><button type ='button' class ='rm' title = 'Remove Row'/></td></tr>") }); $("#myTable").on('click', '.rm', function() { $(this).parent().parent().remove(); }); }); function post() { $.ajax({ type: "POST", contentType: 'application/json; charset=utf-8', dataType: 'json', url: "query", data: JSON.stringify($('form').serializeArray()) }) }; 
 <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> </head> <form> <table> <tbod> <tr> <td>Field: <select name='field'> <option>a</option> <option>b</option> <option>c</option> <option>d</option> </select> </td> <td> <select name='filter'> <option>Contains</option> <option>Does Not Contain</option> <option>Equals</option> <option>Does Not Equal</option> </select> </td> <td> <input name='criteria' type='text'> </td> </tr> </tbod> </table> <table id='myTable'> <tbody> </tbody> </table> <input type="button" value="search" onclick="return post();"> <input type="button" id="theButton" value="Add Criteria"> </form> 

UPDATE

I attempted to do something a little simpler to narrow down the issue and from what I have looked up it seems to be a problem with the jackson mapping. The following code produces 415 error as well.

Controller

@RestController
public class Rest{
@RequestMapping(value="/testModel",method=RequestMethod.GET)
public ModelAndView getTestModel(){
   return new ModelAndView("testModel");
}

 @RequestMapping(value="/sendTestModel",method=RequestMethod.POST)
 public String submiteTestModel(@RequestBody TestModel test){
   return test.getName();
 }
 }

MODEL

public class TestModel{

private String id;
private String name;

//getters setters....
}

testModel.jsp

 function post() { $.ajax({ headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, type: "POST", contentType: 'application/json;, dataType: ' json ', url: "sendTestModel", data: JSON.stringify({id:"1",name:"Bob"}) }) }; 
 <Html> <input type="button" value="search" onclick="return post();"/> </Html> 

Calling JSON.stringify($('form').serializeArray()) will give you the following String

[{"name":"field","value":"a"},{"name":"filter","value":"Contains"},{"name":"criteria","value":""}]

Here is the documentation for serializeArray()

Clearly, this is not acceptable for a @RestController that expects JSON representation of Criterias object. Your JSON string should look like

{"criteria":[{"field":"a","filter":"Contains"},{"field":"Some other field value","filter":"Some other filter value"}]}

I have made a simple function to do it for you :

function convertCriterias(json){
    var o = new Object();
    var criterias = [];
    var c = new Object();

    for(var i = 0; i < json.length; i++){
        c[json[i].name] = json[i].value;
    }

    criterias[0] = c;

    o.criteria = criterias;

    return JSON.stringify(o);
}

Just replace JSON.stringify($('form').serializeArray()) with convertCriterias($('form').serializeArray())

EDIT

I believe you meant to use input type="button" instead of input type="submit" for doing an AJAX post to your @RestController . And you meant to call return work() and not return post in the onclick event of the button.

Try the following options:

  • Add in your controller's RequestMapping the content-type you want to get produced. Take a look at the Producible Media Types documentation for more information.

    @ResponseBody @RequestMapping(value="/query", method=RequestMethod.POST, produces="application/json")

  • Explicitly specify the Accept request header not just the Content-Type header in your jQuery Ajax call:

    $.ajax({
    headers: {
    Accept : "application/json; charset=utf-8",
    "Content-Type": "application/json; charset=utf-8"
    },.. })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM