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,即使我们迁移活性堆栈,现在我们有知识做所有这些事情。