1. Overview
1.概述
In this quick tutorial, we’ll explore the different ways of setting a header on a service response, either for non-reactive endpoints or APIs, using Spring 5’s WebFlux framework.
在本快速教程中,我们将使用Spring 5的WebFlux框架,探讨在服务响应中设置头的不同方式,无论是针对非响应式端点还是API。
We can find further information about this framework in previous posts.
我们可以在以前的文章中找到关于这个框架的进一步信息。
2. Headers for Non-Reactive Components
2.非反应性元件的标头
If we want to set headers on single responses, we can use HttpServletResponse or ResponseEntity objects.
如果我们想在单个响应上设置头信息,我们可以使用HttpServletResponse或ResponseEntity对象。
In contrast, if our objective is to add a filter to all or multiple responses, we’ll need to configure a Filter.
相反,如果我们的目标是向所有或多个响应添加一个过滤器,我们就需要配置一个Filter。
2.1. Using HttpServletResponse
2.1.使用HttpServletResponse
We simply have to add the HttpServletResponse object to our REST endpoint as an argument, and then use the addHeader() method:
我们只需将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";
}
As shown in the above example, we don’t have to return the response object.
如上例所示,我们不需要返回响应对象。
2.2. Using ResponseEntity
2.2.使用ResponseEntity
In this case, we’ll use the BodyBuilder provided by the ResponseEntity class:
在这种情况下,我们将使用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");
}
The HttpHeaders class offers plenty of convenience methods to set the most common headers.
HttpHeaders类提供了大量方便的方法来设置最常见的头文件。
We can see more examples illustrating these points in our Github repo.
我们可以在我们的Github repo中看到更多说明这些观点的例子。
2.3. Adding a Header for All Responses
2.3.为所有响应添加一个头
Now let’s imagine we want to set a particular header to many of our endpoints.
现在,让我们想象一下,我们想为我们的许多端点设置一个特定的头。
Of course, it would be frustrating if we had to replicate the previous code on each mapping method.
当然,如果我们不得不在每个映射方法上复制之前的代码,那就很令人沮丧了。
A better approach to accomplishing this is by configuring a Filter in our service:
一个更好的方法是通过在我们的服务中配置一个Filter来实现这个目的。
@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() {
// ...
}
}
The @WebFilter annotation allows us to indicate the urlPatterns for which this Filter will become effective.
@WebFilter注解允许我们指示urlPatterns,对于这些Filter将生效。
As we pointed out in this article, in order to make our Filter discoverable by Spring, we need to add the @ServletComponentScan annotation to our Spring Application class:
正如我们在本文中指出的,为了使我们的Filter能够被Spring发现,我们需要将@ServletComponentScanannotation添加到我们的Spring应用类中。
@ServletComponentScan
@SpringBootApplication
public class ResponseHeadersApplication {
public static void main(String[] args) {
SpringApplication.run(ResponseHeadersApplication.class, args);
}
}
If we don’t need any of the functionality provided by @WebFilter, we can avoid this last step by using the @Component annotation in our Filter class instead.
如果我们不需要@WebFilter提供的任何功能,我们可以通过在我们的Filter类中使用@Component注解来避免这最后一步。
3. Headers for Reactive Endpoints
3.反应式端点的标头
In this section, we’ll learn how to set headers on single endpoint responses using ServerHttpResponse, ResponseEntity or ServerResponse (for functional endpoints) classes and interfaces.
在本节中,我们将学习如何使用ServerHttpResponse、ResponseEntity或ServerResponse(用于功能端点)类和接口在单个端点响应上设置头信息。
We’ll also discuss how to implement a Spring 5 WebFilter to add a header on all of our responses.
我们还将讨论如何实现Spring 5 WebFilter,以便在所有的响应上添加一个头。
3.1. Using ServerHttpResponse
3.1.使用ServerHttpResponse
This approach is fairly similar to the HttpServletResponse counterpart:
这种方法与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. Using ResponseEntity
3.2.使用ResponseEntity
We can use the ResponseEntity class exactly as we do for non-reactive endpoints:
我们可以像对待非反应式端点那样使用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. Using ServerResponse
3.3.使用ServerResponse
The classes and interfaces introduced in the last two sub-sections can be used in @Controller annotated classes, but aren’t suitable for the new Spring 5 Functional Web Framework.
上两小节介绍的类和接口可以用于@Controller注释的类,但不适合新的Spring 5 Functional Web框架。
If we want to set a header on a HandlerFunction, then we’ll need to get our hands on the ServerResponse interface:
如果我们想在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. Adding a Header for All Responses
3.4.为所有响应添加一个头
Finally, Spring 5 provides a WebFilter interface to set a header on all the responses retrieved by a service:
最后,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. Conclusion
4.总结
In this article, we learned many different ways of setting a header on a response. Now whether we want to set it on a single endpoint, configure all our rest APIs, or even migrate to the reactive stack, we have the knowledge necessary.
在这篇文章中,我们学习了许多在响应上设置头的不同方法。现在,无论我们想在一个单一的端点上设置它,还是配置我们所有的休息API,甚至迁移到反应堆,我们都有必要的知识。
As always, all the examples can be accessed in our Github repository, both the non-reactive ones and those using Spring 5 specific functionality.
一如既往,所有示例都可以在我们的 Github 仓库中访问,包括非反应式的示例和使用Spring 5 特定功能的示例。