#java #json #spring #rest #spring-mvc
#java #json #spring #rest #spring-mvc
Вопрос:
Я пытаюсь создать REST api для своего приложения. Основы выполнены. Но теперь мне нужна помощь для поиска с различными параметрами и их операндами.
Допустим, у меня есть строка JSON, подобная этой:
{"v00Datvon":"09-07-2014","v00Datbis":"09-07-2014","v00Saicode":{"saiCode":"SO02"}}
Это значения моего доменного объекта «contract».
Для поиска в части пользовательского интерфейса вы можете выбрать для двух дат операнд (больший, меньший или равный)
Все параметры (без операндов) отправляются при вызове GET и Ajax.
Контроллер Spring MVC выглядит следующим образом:
@RequestMapping(value = "/", method = RequestMethod.GET, headers = "Accept=application/json")
public ResponseEntity<String> getContractsFromSearch(@RequestParam String allRequestParams, ModelMap model){
//some stuff
}
Я ищу техническую информацию, как добавить операнды в строку JSON и контроллер чистым и хорошим способом. Я не хочу взламывать какой-то плохой код.
Если вам нужно больше информации, пожалуйста, оставьте комментарий.
Спасибо!
Обновление 1.
ПОЛУЧИТЬ запрос:
allRequestParams={"v00Datvon":"09-07-2014","v00Datbis":"09-07-2014","v00Saicode":{"saiCode":"SO02"}}
Обновление 2.
{
"dateFrom": {
"dateFrom": "someDate",
"operand": "less"
},
"dateTo": {
"dateTo": "someDate",
"operand": "greater"
},
"season": {
"season": "someSeason",
"operand": "equals"
}
}
Обновление 3
Десериализация:
public static Contract fromJsonToContract(String json) {
return new JSONDeserializer<Contract>().use(Calendar.class, new CalendarTransformer("dd-MM-yyyy HH:mm")).use(null, Contract.class).deserialize(json);
}
Комментарии:
1. Не могли бы вы, пожалуйста, показать нам пример
GET
запроса? Как выглядят параметры в URL-адресе?2. На данный момент я не добавляю операнды в параметры. Я не уверен, что смогу сделать это хорошим способом.
3. Есть другие предложения?
4. Используйте кодировку ISO-8601 для дат.
GET
URL выглядит как find.5. GET URL работает нормально. Проблема не в этом. Мне нужна помощь, чтобы добавить параметры операндов к этому URL. Чистым и хорошим способом. Может быть, будут какие-то стандарты? Спасибо
Ответ №1:
Прежде всего, в соответствии с вашим контроллером, как вы передаете Map как RequestParam, это невозможно, попробуйте это
@RequestMapping(value = "/", method = RequestMethod.GET, headers = "Accept=application/json")
public ResponseEntity<String> getContractsFromSearch(HttpServletRequest request, Object> allRequestParams, ModelMap model){
Enumeration paramNames = request.getParameterNames();
while(paramNames.hasMoreElements())
{
String paramName =
(String)paramNames.nextElement();
out.print(paramName);
}
//some stuff
}
Комментарии:
1. Карта работает нормально. Вывод карты выглядит следующим образом:
{dateFrom=02-07-2014, dateTo=02-07-2014, season=SO03}
Но есть ли у вас какие-либо предложения по добавлению операндов в список параметров вашего решения?2. Есть другие предложения?
3. перед переходом к вашему контроллеру установите некоторую логику фильтрации, к которой вы можете легко добавлять операнды
4. ОК. Но как должен выглядеть json? Как в обновлении 2, о котором идет речь? Или есть какой-то стандарт?
5. да, вы можете предпочесть update2 json, который выглядит осмысленно
Ответ №2:
Я думаю, что ваш JSON слишком подробный: у вас есть запись с именем «DateFrom», в которой есть запись с именем «DateFrom», постарайтесь, чтобы она была простой и «плоской». Как насчет этой опции?:
{
"dateFrom": "someDate",
"operandFrom": "less",
"dateTo": "someDate",
"operandTo": "greater",
"season": "someSeason",
"operandSeason": "equals"
}
Я знаю, что группировать данные по семантике заманчиво, но в запросе GET вы должны продумать наилучший способ обработки параметров.Данные могут быть легко преобразованы в:
dateFrom=someDateamp;operandFrom=lessamp;dateTo=someDateamp;operandTo=greateramp;season=someSeasonamp;operandSeason=equals
или просто отправьте один параметр с JSON в качестве значения:
q={"dateFrom": "someDate","operandFrom":"less","dateTo":"someDate","operandTo":"greater","season":"someSeason","operandSeason":"equals"}
Но тогда вам нужно было бы проанализировать его в вашем контроллере.