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

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

1. обзор

В этом кратком руководствеwe’ll go through different ways of setting a header on a service response либо для нереактивных конечных точек, либо для API, использующихSpring’s 5 WebFlux framework.

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

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

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

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

2.1. ИспользуяHttpServletResponse

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

@GetMapping("/http-servlet-response")
public String usingHttpServletResponse(HttpServletResponse response) {
    response.addHeader("example-Example-Header", "Value-HttpServletResponse");
    return "Response with header using HttpServletResponse";
}

Как показано в примере, нам не нужно возвращать объект ответа.

2.2. ИспользуяResponseEntity

В этом случае давайте использоватьBodyBuilder, предоставленный классомResponseEntity:

@GetMapping("/response-entity-builder-with-http-headers")
public ResponseEntity usingResponseEntityBuilderAndHttpHeaders() {
    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.set("example-Example-Header",
      "Value-ResponseEntityBuilderWithHttpHeaders");

    return ResponseEntity.ok()
      .headers(responseHeaders)
      .body("Response with header using ResponseEntity");
}

КлассHttpHeaders предлагает множество удобных методов для установки наиболее распространенных заголовков.

Мы можем увидеть больше примеров, иллюстрирующих эти точки вour Github repo.

2.3. Добавление заголовка для всех ответов

А теперь представим, что мы хотим установить определенный заголовок для многих наших конечных точек.

Конечно, было бы неприятно, если бы нам пришлось копировать предыдущий код для каждого метода отображения.

Для этого лучше использоватьconfiguring a Filter in our service:

@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(
          "example-Example-Filter-Header", "Value-Filter");
        chain.doFilter(request, response);
    }

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

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

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

Как мы уже указывалиin this article, чтобы сделать нашFilter обнаруживаемым Spring, нам нужно добавить саннотацию@ServletComponentScan к нашему классу Spring Application:

@ServletComponentScan
@SpringBootApplication
public class ResponseHeadersApplication {

    public static void main(String[] args) {
        SpringApplication.run(ResponseHeadersApplication.class, args);
    }
}

Мы можем избежать этого последнего шага, если нам не нужны какие-либо функции, предоставляемые@WebFilter, используя вместо этого аннотацию@Component в нашем классеFilter.

3. Заголовки для реактивных конечных точек

Опять же, мы увидим, как установить заголовки в ответах одной конечной точки, используя классы и интерфейсыServerHttpResponse,ResponseEntity orServerResponse (для функциональных конечных точек).

Мы также узнаем, как реализовать Spring 5WebFilter, чтобы добавить заголовок ко всем нашим ответам.

3.1. ИспользуяServerHttpResponse

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

@GetMapping("/server-http-response")
public Mono usingServerHttpResponse(ServerHttpResponse response) {
    response.getHeaders().add("example-Example-Header", "Value-ServerHttpResponse");
    return Mono.just("Response with header using ServerHttpResponse");
}

3.2. ИспользуяResponseEntity

Мы можем использовать классResponseEntity точно так же, как и для нереактивных конечных точек:

@GetMapping("/response-entity")
public Mono> usingResponseEntityBuilder() {
    String responseHeaderKey = "example-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 Functional Web Framework.

Если нам нужен интерфейсto set a header on a HandlerFunction then we’ll need to get our hands on the ServerResponse:

public Mono useHandler(final ServerRequest request) {
     return ServerResponse.ok()
        .header("example-Example-Header", "Value-Handler")
        .body(Mono.just("Response with header using Handler"),String.class);
}

3.4. Добавление заголовка для всех ответов

Наконец,Spring 5 provides a WebFilter interface to set a header on all the responses, полученный службой:

@Component
public class AddResponseHeaderWebFilter implements WebFilter {

    @Override
    public Mono filter(ServerWebExchange exchange, WebFilterChain chain) {
        exchange.getResponse()
          .getHeaders()
          .add("example-Example-Filter-Header", "Value-Filter");
        return chain.filter(exchange);
    }
}

4. Заключение

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

Как всегда, все примеры доступны в нашем репозитории Github, какnon-reactive ones, так и те, которые используютSpring 5 specific functionality.