Что возвращать, если метод контроллера Spring MVC не возвращает значение?

135

Я использую jQuery $.getJSON()для выполнения асинхронных вызовов моего простого бэкэнда Spring MVC. Большинство методов контроллера Spring выглядят так:

@RequestMapping(value = "/someURL", method = RequestMethod.POST)
public @ResponseBody SomePOJO getSomeData(@ModelAttribute Widget widget,
    @RequestParam("type") String type) {
    return someDAO.getSomeData(widget, type);
}   

У меня все настроено так, что каждый контроллер возвращает @ResponseBodyкак JSON, что и ожидает клиентская сторона.

Но что происходит, если запрос не должен возвращать какой-либо контент на стороне клиента? Можно мне:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
public @ResponseBody void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

Если нет, то какой синтаксис здесь использовать?

IAmYourFaja
источник
Полагаю, если вы ничего не вернете, никакого контента не будет отправлено обратно?
arahant
1
Я думаю, что я все равно верну какой-нибудь POJO, даже если в версии 1 вашего решения он просто обертывает логическое значение «success» или что-то подобное. Тогда у вас есть последовательный образец во всех ваших методах AJAX, и то , что легче построить, когда оказывается, вы делаете необходимость вернуть что - то!
Millhouse
Вопреки предложению ответов, то, что у вас было сначала во втором фрагменте, совершенно нормально и является правильным способом обработки POSTданных.
Бретт Райан
В этом случае он вернет null. @RestController открытый класс RESTControllerExample {@RequestMapping (value = "/ employee", method = RequestMethod.GET) public void getEmployeeNames () {EmployeeSource.getEmployees (); System.out.println («Я закончил»); }}
spandey

Ответы:

256

вы можете вернуть void, тогда вам нужно пометить метод с помощью @ResponseStatus (value = HttpStatus.OK), вам не нужен @ResponseBody

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

Только методы get возвращают значение кода состояния 200, все остальные, которые у вас есть, делают одно из трех:

  • Верните void и отметьте метод @ResponseStatus(value = HttpStatus.OK)
  • Вернуть объект и пометить его @ResponseBody
  • Вернуть HttpEntityэкземпляр
военно-картографическая служба
источник
2
В случае, если между ними произойдет исключение времени выполнения, будет возвращен HTTP 500, а не 200. Таким образом, если ваш интерфейсный дескриптор не работает, сообщение об исключении / ошибке будет отображаться правильно.
Ли Чи Киам,
27
Собственно, устанавливать не надо @ResponseStatusи не надо. Просто имея @ResponseBodyна voidобработчик отлично достаточно.
Бретт Райан
11
Думаю, будет лучше вернуть 204 No Content вместо 200 для void-методов
raspacorp
1
@raspacorp 200 подходит для POST, так как не имеет тела.
Бретт Райан
8
@BrettRyan просто в качестве комментария, по крайней мере, для REST API, это обычная практика, когда POST будет использоваться для создания контента, и в этом случае он обычно возвращает идентификатор созданных объектов, полные созданные объекты или ссылку к операции чтения. Возврат статуса 200 без содержания может сбивать с толку с точки зрения REST API.
raspacorp
43

Вы можете просто вернуть ResponseEntity с соответствующим заголовком:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
public ResponseEntity updateDataThatDoesntRequireClientToBeNotified(...){
....
return new ResponseEntity(HttpStatus.OK)
}
Biju Kunjummen
источник
Если кто-то столкнется с той же проблемой, что и я, это не сработало в более старой версии spring (4.1.1), я бы получил 500 ошибок. Я обновился до 4.2.0, и это отлично работает
соус
Это мой предпочтительный способ вернуть пустые 200. Начиная с Spring 4.1, вместо этого используйте шаблон построителя: return ResponseEntity.ok (). Build ();
GreenTurtle
3
Хотя кажется, что он компилируется, он дает следующее предупреждениеResponseEntity is a raw type. References to generic type ResponseEntity<T> should be parameterized
Gonzalo.-
8

Вы можете вернуть объект ResponseEntity. Использование объекта ResponseEntity очень удобно как во время создания объекта ответа (который содержит тело ответа и код состояния HTTP), так и во время получения информации из объекта ответа.

Такие методы, как getHeaders (), getBody (), getContentType (), getStatusCode () и т. Д., Делают работу по чтению объекта ResponseEntity очень простой.

Вы должны использовать объект ResponseEntity с кодом состояния http 204 (без содержимого), который специально указывает, что запрос был обработан правильно, а тело ответа намеренно пустое. Использование соответствующих кодов состояния для передачи правильной информации очень важно, особенно если вы создаете API, который будет использоваться несколькими клиентскими приложениями.

Harley
источник
3
настройка @ResponseStatus(HttpStatus.NO_CONTENT)решена XML Parsing Error: no root element foundдля меня в браузере
aliopi
3

Да, вы можете использовать @ResponseBody с voidтипом возврата:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
@ResponseBody
public void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}
user1338062
источник
1
Итак, какой будет тип возврата .. это код состояния HTTP?
spandey
@techBeginner В данном случае 200 (ОК).
Лакатош Дьюла
2

Нет ничего плохого в том, чтобы вернуть пустоту, @ResponseBodyи вы должныPOST запросов.

Вместо этого используйте коды состояния HTTP для определения ошибок в процедурах обработчика исключений, поскольку другие упоминают статус успеха. Обычный метод, который у вас есть, вернет код ответа, 200который вы хотите, любой обработчик исключений может затем вернуть объект ошибки и другой код (т.е. 500).

Бретт Райан
источник
1

Но по мере того, как ваша система растет в размере и функциональности ... я думаю, что всегда возвращать json - неплохая идея. Это скорее вопрос архитектуры / «крупномасштабного дизайна».

Вы можете всегда думать о сохранении JSON с двумя известными полями: кодом и данными. Где code - это числовой код, определяющий успех операции, которую нужно выполнить, а data - любые дополнительные данные, связанные с запрошенной операцией / услугой.

Да ладно, когда мы используем серверную часть поставщика услуг, любую услугу можно проверить, чтобы увидеть, хорошо ли она работает.

Поэтому я придерживаюсь того, чтобы Spring не справлялся с этим, выставляя гибридные операции возврата (некоторые возвращают данные, другие ничего ...). Убедитесь, что ваш сервер предоставляет более однородный интерфейс. В конце концов, это проще.

Виктор
источник
0

Вот пример кода того, что я сделал для асинхронного метода

@RequestMapping(value = "/import", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void importDataFromFile(@RequestParam("file") MultipartFile file) 
{
    accountingSystemHandler.importData(file, assignChargeCodes);
}

Вам не нужно ничего возвращать из вашего метода, все, что вам нужно, чтобы использовать эту аннотацию, чтобы ваш метод возвращал OK в каждом случае

@ResponseStatus(value = HttpStatus.OK)
Абдуссалама
источник