Reputation: 5
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>
Upvotes: 0
Views: 7231
Reputation: 5474
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.
Upvotes: 2
Reputation: 21411
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"
},.. })
Upvotes: 0