Использование Spring ResponseEntity для манипулирования HTTP-ответом

Использование Spring ResponseEntity для управления HTTP-ответом

1. Вступление

Используя Spring, у нас обычно есть много способов достичь той же цели, включая тонкую настройку HTTP-ответов.

В этом коротком руководстве мы увидим, как установить текст, статус и заголовки HTTP-ответа с помощьюResponseEntity.

Дальнейшее чтение:

Получение и проверка данных ответа с гарантированным REST

Посмотрите, как использовать REST-гарантированный для проверки и извлечения ответа из конечной точки REST

Read more

Использование Spring @ResponseStatus для установки кода состояния HTTP

Посмотрите на аннотацию @ResponseStatus и как использовать ее для установки кода состояния ответа.

Read more

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.