2015-10-13 1 views
0

Привет, поэтому у меня возникают проблемы с получением JSON из моей формы в мою работу с весной mvc. Моя форма динамична, и JSON возвращается как список критериев, которые пользователь заполнил в форме. В идеале я хотел бы получить JSON, чтобы он появился как объект Criterias, который содержит список объектов Criteria. (Как и мои классы моделей ниже) Я не знаю, возможно ли это, или если есть другой способ пойти по этому поводу, но любые советы будут высоко оценены.ajax json Post to Spring mvc Контроллер «415 Неподдерживаемый тип носителя»

** В настоящее время я получаю 415 неподдерживаемый тип носителя из сообщения ajax.

КОНТРОЛЛЕР

@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"); 

} 

МОДЕЛЬ

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

Я попытался сделать что-то более простое, чтобы сузить проблему и от того, что я искал, кажется, проблема с картографией Джексона. Следующий код также вызывает ошибку 415.

Контроллер

@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(); 
} 
} 

МОДЕЛЬ

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>

ответ

1

Вызов JSON.stringify($('form').serializeArray()) даст вам следующую строку

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

Вот является documentation для serializeArray()

Очевидно, что это не приемлемо для @RestController, ожидающей JSON представление Объект Criterias. Ваш JSON строка должна выглядеть

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

Я сделал простую функцию, чтобы сделать это для вас:

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); 
} 

Просто замените JSON.stringify($('form').serializeArray()) с convertCriterias($('form').serializeArray())

EDIT

Я полагаю, вы хотели использовать input type="button" вместо input type="submit" за сообщение AJAX на ваш @RestController. И вы намеревались позвонить return work(), а не return post в событии onclick.

+0

Кажется, что ваша функция захватывает только одну группу критериев, вместо того чтобы возвращать {«критерии»: [{«поле»: «a», «фильтр»: «содержит»}, {«поле»: «другое значение поля», , "filter": "Some other filter value"}]} Он возвращает только последнюю строку того, что было выбрано в моей форме. так как это {«критерии»: [{имена и значения полей}]} –

+0

Это потому, что у вас есть только одно поле и один фильтр в вашей форме. Если 'serializeArray' возвращает много полей и многих фильтров, они будут помещены в возвращаемую строку JSON. Что касается вашей основной проблемы, сообщите мне, объяснил ли я вам основную причину, по которой вы получаете «415 неподдерживаемый тип носителя» из вашего запроса. – Bnrdo

+0

Есть больше, чем на поле и фильтр в моей форме? если вы запустите фрагмент кода, вы увидите, что если вы нажмете «Добавить критерии», он добавит в форму новые фильтры полей и значения. Я попробовал backtracking и попытался посмотреть, могу ли я сопоставить только один объект с моим JSON, и я все еще получил 415 неподдерживаемую ошибку Media Type –

0

Попробуйте следующие варианты:

  • Добавить в вашем диспетчерском RequestMapping типа содержимого, который вы хотите получить производство. Взгляните на Producible Media Types documentation для получения дополнительной информации.

    @ResponseBody @RequestMapping (значение = "/ запрос", метод = RequestMethod.POST, производит = "приложения/JSON")

  • явно указать заголовок запроса на Принять не только Content-Type заголовок в вызове JQuery Ajax:

    $ .ajax ({
    заголовки: {
    Accept: "приложения/JSON; Charset = UTF-8",
    "Content-Type": «применение/JS на; charset = utf-8 "
    }, ..})

+0

Благодарим за ответ, но я все еще получаю такую ​​же ошибку 415. –

Смежные вопросы