1. 概述

在这个快速教程中,我们将介绍在服务响应上设置头的不同方法,无论是针对非反应性端点,还是针对使用Spring 5 WebFlux框架的api。

我们可以在以前的文章中找到关于这个框架的更多信息。

2. 非反应性组件的header

如果我们想设置单个响应的头,我们可以使用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

在这种情况下,让我们使用ResponseEntity类提供的BodyBuilder:

@GetMapping("/response-entity-builder-with-http-headers")public ResponseEntity usingResponseEntityBuilderAndHttpHeaders() {    HttpHeaders responseHeaders = new HttpHeaders();    responseHeaders.set("Baeldung-Example-Header",      "Value-ResponseEntityBuilderWithHttpHeaders");    return ResponseEntity.ok()      .headers(responseHeaders)      .body("Response with header using ResponseEntity");}

HttpHeaders类提供了许多方便的方法来设置最常见的头信息。

2.3. 为所有响应添加header

现在假设我们想要为许多端点设置一个特定的头。

当然,如果我们必须在每个映射方法上复制前面的代码,那将是令人沮丧的。

更好的方法是在我们的服务中配置一个过滤器:

@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注释允许我们指出这个过滤器将对哪些urlPatterns有效。

正如我们在本文中指出的,为了让我们的过滤器被Spring发现,我们需要在Spring应用程序类中添加@ServletComponentScan注释:

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

如果我们不需要@WebFilter提供的任何功能,我们可以通过在过滤器类中使用@Component注释来避免这最后一步。

3.响应性header

同样,我们将看到如何使用ServerHttpResponse、ResponseEntity或ServerResponse(针对功能性端点)类和接口在单个端点响应上设置报头。

我们还将学习如何实现一个Spring 5 WebFilter来在所有的响应中添加一个头。

3.1. 使用ServerHttpResponse

此方法与对应的HttpServletResponse非常相似:

@GetMapping("/server-http-response")public Mono 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> 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 Functional Web框架。

如果我们想在HandlerFunction上设置一个头,那么我们需要得到ServerResponse接口:

public Mono 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. 为所有响应添加header

最后,Spring 5提供了一个WebFilter接口来为服务检索到的所有响应设置一个头:

@Componentpublic class AddResponseHeaderWebFilter implements WebFilter {    @Override    public Mono filter(ServerWebExchange exchange, WebFilterChain chain) {        exchange.getResponse()          .getHeaders()          .add("Baeldung-Example-Filter-Header", "Value-Filter");        return chain.filter(exchange);    }}

4. 结论

总之,我们学到许多不同的方式设置一个头的反应,如果我们想要把它放在一个端点或如果我们想配置所有rest api,即使我们迁移活性堆栈,现在我们有知识做所有这些事情。