Перейти к основному содержимому

Как установить заголовок в ответ с помощью Spring 5

· 4 мин. чтения

1. Обзор

В этом кратком руководстве мы рассмотрим различные способы установки заголовка в ответе службы либо для нереактивных конечных точек, либо для API-интерфейсов, использующих платформу Spring 5 WebFlux .

Дополнительную информацию об этом фреймворке мы можем найти в предыдущих постах .

2. Заголовки для нереактивных компонентов

Если мы хотим установить заголовки для отдельных ответов, мы можем использовать объекты HttpServletResponse или ResponseEntity .

С другой стороны, если наша цель — добавить фильтр ко всем или нескольким ответам, нам потребуется настроить Filter .

2.1. Использование HttpServletResponse

Нам просто нужно добавить объект HttpServletResponse в нашу конечную точку REST в качестве аргумента, а затем использовать метод addHeader() :

@GetMapping("/http-servlet-response")
public String usingHttpServletResponse(HttpServletResponse response) {
response.addHeader("ForEach-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("ForEach-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(
"ForEach-Example-Filter-Header", "Value-Filter");
chain.doFilter(request, response);
}

@Override
public void init(FilterConfig filterConfig) throws ServletException {
// ...
}

@Override
public void destroy() {
// ...
}
}

Аннотация @WebFilter позволяет нам указать urlPatterns, для которых этот фильтр станет эффективным.

Как мы указывали в этой статье , чтобы 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. Использование сервераHttpResponse

Этот подход очень похож на аналог HttpServletResponse :

@GetMapping("/server-http-response")
public Mono<String> usingServerHttpResponse(ServerHttpResponse response) {
response.getHeaders().add("ForEach-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 = "ForEach-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("ForEach-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("ForEach-Example-Filter-Header", "Value-Filter");
return chain.filter(exchange);
}
}

4. Вывод

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

Как всегда, все примеры доступны в нашем репозитории Github, как нереактивные, так и использующие специфические функции Spring 5 .