Использование Spring ResponseEntity для управления HTTP-ответом
1. Вступление
Используя Spring, у нас обычно есть много способов достичь той же цели, включая тонкую настройку HTTP-ответов.
В этом коротком руководстве мы увидим, как установить текст, статус и заголовки HTTP-ответа с помощьюResponseEntity.
Дальнейшее чтение:
Получение и проверка данных ответа с гарантированным REST
Посмотрите, как использовать REST-гарантированный для проверки и извлечения ответа из конечной точки REST
Использование Spring @ResponseStatus для установки кода состояния HTTP
Посмотрите на аннотацию @ResponseStatus и как использовать ее для установки кода состояния ответа.
2. ResponseEntityс
ResponseEntityrepresents the whole HTTP response: status code, headers, and body. Из-за этого мы можем использовать его для полной настройки HTTP-ответа.
Если мы хотим использовать его, мы должны вернуть его из конечной точки; Весна позаботится обо всем остальном.
ResponseEntity - это общий тип. В результате мы можем использовать любой тип в качестве тела ответа:
@GetMapping("/hello")
ResponseEntity hello() {
return new ResponseEntity<>("Hello World!", HttpStatus.OK);
}
Поскольку мы указываем статус ответа программно, мы можем вернуться с разными кодами состояния для разных сценариев:
@GetMapping("/age")
ResponseEntity age(
@RequestParam("yearOfBirth") int yearOfBirth) {
if (isInFuture(yearOfBirth)) {
return new ResponseEntity<>(
"Year of birth cannot be in the future",
HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>(
"Your age is " + calculateAge(yearOfBirth),
HttpStatus.OK);
}
Кроме того, мы можем установить заголовки HTTP:
@GetMapping("/customHeader")
ResponseEntity customHeader() {
HttpHeaders headers = new HttpHeaders();
headers.add("Custom-Header", "foo");
return new ResponseEntity<>(
"Custom header set", headers, HttpStatus.OK);
}
Кроме того,ResponseEntityprovides two nested builder interfaces:HeadersBuilder и его подинтерфейсBodyBuilder. Следовательно, мы можем получить доступ к их возможностям с помощью статических методовResponseEntity.
Простейший случай - это ответ с телом и кодом ответа HTTP 200:
@GetMapping("/hello")
ResponseEntity hello() {
return ResponseEntity.ok("Hello World!");
}
Для самых популярных кодов состояния HTTP мы получаем статические методы:
BodyBuilder accepted();
BodyBuilder badRequest();
BodyBuilder created(java.net.URI location);
HeadersBuilder> noContent();
HeadersBuilder> notFound();
BodyBuilder ok();
Кроме того, мы можем использовать методыBodyBuilder status(HttpStatus status) иBodyBuilder status(int status) для установки любого статуса HTTP.
Наконец, с помощьюResponseEntity<T> BodyBuilder.body(T body) мы можем установить тело ответа HTTP:
@GetMapping("/age")
ResponseEntity age(@RequestParam("yearOfBirth") int yearOfBirth) {
if (isInFuture(yearOfBirth)) {
return ResponseEntity.badRequest()
.body("Year of birth cannot be in the future");
}
return ResponseEntity.status(HttpStatus.OK)
.body("Your age is " + calculateAge(yearOfBirth));
}
Мы также можем установить пользовательские заголовки:
@GetMapping("/customHeader")
ResponseEntity customHeader() {
return ResponseEntity.ok()
.header("Custom-Header", "foo")
.body("Custom header set");
}
Следовательно,BodyBuilder.body() возвращаетResponseEntity вместоBodyBuilder,, это должен быть последний вызов.
Обратите внимание, что с помощьюHeaderBuilder мы не можем установить какие-либо свойства тела ответа.
При возврате объектаResponseEntity<T> из контроллера мы можем получить какое-то исключение или ошибку при обработке запроса и хотели бы получитьreturn error-related information to the user represented as some other type let’s say E.
Spring 3.2 обеспечивает поддержку глобального@ExceptionHandler with the new @ControllerAdvice annotation, обрабатывающего такие сценарии. Для получения более подробной информации обратитесь к нашей существующей статьеhere.
While ResponseEntity is very powerful, we shouldn’t overuse it. В простых случаях есть другие варианты, которые удовлетворяют наши потребности, и они приводят к гораздо более чистому коду.
3. альтернативы
3.1. @ResponseBodyс
В классических приложениях Spring MVC конечные точки обычно возвращают визуализированные HTML-страницы. Иногда нам нужно только вернуть фактические данные, например, когда мы используем конечную точку с AJAX.
В таких случаях мы можем пометить метод обработчика запросов@ResponseBody иSpring treats the result value of the method as the HTTP response body.
Для получения дополнительной информацииthis article is a good place to start.
3.2. @ResponseStatusс
Когда конечная точка успешно возвращается, Spring предоставляет ответ HTTP 200 (ОК). Если конечная точка выдает исключение, Spring ищет обработчик исключений, который сообщает, какой HTTP-статус использовать.
Мы можем пометить эти методы с помощью @ResponseStatus. Следовательно, Springreturns with a custom HTTP status.
Чтобы увидеть больше примеров, посетите нашу статью оcustom status codes.
3.3. Манипулировать ответом напрямую
Spring также позволяет нам напрямую обращаться к объектуjavax.servlet.http.HttpServletResponse; нам нужно только объявить его как аргумент метода:
@GetMapping("/manual")
void manual(HttpServletResponse response) throws IOException {
response.setHeader("Custom-Header", "foo");
response.setStatus(200);
response.getWriter().println("Hello World!");
}
Поскольку Spring предоставляет абстракции и дополнительные возможности над базовой реализацией,we shouldn’t manipulate the response this way.
4. Заключение
В этой статье мы увидели несколько способов с их преимуществами и недостатками для манипулирования HTTP-ответом в Spring.
Как обычно доступны примерыover on GitHub.