«1. Обзор
В этом кратком руководстве мы рассмотрим различные способы установки заголовка в ответе службы либо для нереактивных конечных точек, либо для API-интерфейсов, использующих платформу Spring 5 WebFlux.
Дополнительную информацию об этом фреймворке можно найти в предыдущих постах.
2. Заголовки для нереактивных компонентов
Если мы хотим установить заголовки для отдельных ответов, мы можем использовать объекты HttpServletResponse или ResponseEntity.
С другой стороны, если наша цель — добавить фильтр ко всем или нескольким ответам, нам потребуется настроить фильтр.
2.1. Использование HttpServletResponse
Нам просто нужно добавить объект HttpServletResponse в нашу конечную точку REST в качестве аргумента, а затем использовать метод addHeader():
@GetMapping("/http-servlet-response")
public String usingHttpServletResponse(HttpServletResponse response) {
response.addHeader("Baeldung-Example-Header", "Value-HttpServletResponse");
return "Response with header using HttpServletResponse";
}
Как показано в примере, нам не нужно возвращать ответ объект.
2.2. Использование ResponseEntity
В этом случае воспользуемся BodyBuilder, предоставляемым классом ResponseEntity:
@GetMapping("/response-entity-builder-with-http-headers")
public ResponseEntity<String> usingResponseEntityBuilderAndHttpHeaders() {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("Baeldung-Example-Header",
"Value-ResponseEntityBuilderWithHttpHeaders");
return ResponseEntity.ok()
.headers(responseHeaders)
.body("Response with header using ResponseEntity");
}
Класс HttpHeaders предлагает множество удобных методов для установки наиболее распространенных заголовков.
Мы можем увидеть больше примеров, иллюстрирующих эти моменты, в нашем репозитории Github.
2.3. Добавление заголовка для всех ответов
Теперь давайте представим, что мы хотим установить определенный заголовок для многих наших конечных точек.
Конечно, было бы неприятно, если бы нам пришлось реплицировать предыдущий код для каждого метода сопоставления.
Лучший способ сделать это — настроить фильтр в нашем сервисе:
@WebFilter("/filter-response-header/*")
public class AddResponseHeaderFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setHeader(
"Baeldung-Example-Filter-Header", "Value-Filter");
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// ...
}
@Override
public void destroy() {
// ...
}
}
Аннотация @WebFilter позволяет нам указать шаблоны URL, для которых этот фильтр станет эффективным.
Как мы указывали в этой статье, чтобы сделать наш фильтр доступным для обнаружения Spring, нам нужно добавить аннотацию @ServletComponentScan к нашему классу приложения Spring:
@ServletComponentScan
@SpringBootApplication
public class ResponseHeadersApplication {
public static void main(String[] args) {
SpringApplication.run(ResponseHeadersApplication.class, args);
}
}
Мы можем избежать этого последнего шага, если нам не нужны какие-либо функции, предоставляемые @WebFilter, вместо этого мы используем аннотацию @Component в нашем классе Filter.
3. Заголовки для реактивных конечных точек
Опять же, мы увидим, как устанавливать заголовки для ответов одной конечной точки, используя классы и интерфейсы ServerHttpResponse, ResponseEntity или ServerResponse (для функциональных конечных точек).
Мы также узнаем, как реализовать Spring 5 WebFilter, чтобы добавить заголовок ко всем нашим ответам.
3.1. Использование ServerHttpResponse
Этот подход очень похож на аналог HttpServletResponse:
@GetMapping("/server-http-response")
public Mono<String> usingServerHttpResponse(ServerHttpResponse response) {
response.getHeaders().add("Baeldung-Example-Header", "Value-ServerHttpResponse");
return Mono.just("Response with header using ServerHttpResponse");
}
3.2. Использование ResponseEntity
Мы можем использовать класс ResponseEntity точно так же, как и для нереактивных конечных точек:
@GetMapping("/response-entity")
public Mono<ResponseEntity<String>> usingResponseEntityBuilder() {
String responseHeaderKey = "Baeldung-Example-Header";
String responseHeaderValue = "Value-ResponseEntityBuilder";
String responseBody = "Response with header using ResponseEntity (builder)";
return Mono.just(ResponseEntity.ok()
.header(responseHeaderKey, responseHeaderValue)
.body(responseBody));
}
3.3. Использование ServerResponse
Классы и интерфейсы, представленные в двух последних подразделах, можно использовать в аннотированных классах @Controller, но они не подходят для новой функциональной веб-инфраструктуры Spring 5.
Если мы хотим установить заголовок для HandlerFunction, нам нужно получить доступ к интерфейсу ServerResponse:
public Mono<ServerResponse> useHandler(final ServerRequest request) {
return ServerResponse.ok()
.header("Baeldung-Example-Header", "Value-Handler")
.body(Mono.just("Response with header using Handler"),String.class);
}
3.4. Добавление заголовка для всех ответов
Наконец, Spring 5 предоставляет интерфейс WebFilter для установки заголовка для всех ответов, полученных службой:
@Component
public class AddResponseHeaderWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
exchange.getResponse()
.getHeaders()
.add("Baeldung-Example-Filter-Header", "Value-Filter");
return chain.filter(exchange);
}
}
4. Заключение
В заключение, мы узнали много нового. различные способы установки заголовка в ответе, либо если мы хотим установить его на одной конечной точке, либо если мы хотим настроить все наши остальные API, даже если мы переходим на реактивный стек, теперь у нас есть знания, чтобы сделать все эти вещи.
Как всегда, все примеры доступны в нашем репозитории Github, как нереактивные, так и использующие специфические функции Spring 5.