Spring MVC设置请求头和响应头的Header
在Spring MVC中,动态设置请求头和响应头的方法有多种,以下是一些常见的方式:
设置请求头
使用@RequestHeader注解
这个注解用于读取请求中的单个HTTP头部值,并将其作为一个参数传递给控制器方法。
@RequestMapping("/example")
public String handleRequest(@RequestHeader(name = "X-Custom-Header", required = false) String customHeaderValue) {
// 使用customHeaderValue...
return "viewName";
}
使用ControllerAdvice
通过ControllerAdvice类,你可以全局地添加响应头。
@ControllerAdvice
public class GlobalHeaderControllerAdvice {
@AfterResponseBodyAdvice
public void addGlobalHeader(@RequestHeader HttpHeaders headers) {
headers.set("X-Global-Response-Header", "GlobalValue");
}
}
使用@RequestMapping注解的headers属性
对于@RequestMapping及其派生注解(如@GetMapping、@PostMapping等),可以使用headers属性来指定请求的约束条件,这可以用来模拟请求头的效果。
@RequestMapping(value = "/example", method = RequestMethod.GET, headers = "X-Custom-Header=someValue")
public String conditionalRequestMapping() {
// 方法实现...
}
使用HttpServletRequest
通过注入HttpServletRequest
对象,可以读取和修改请求头(通常用于读取,因为HTTP请求头在请求到达servlet时已经设置好了,不能修改)。
@RequestMapping("/example")
public String handleRequest(HttpServletRequest request) {
String customValue = request.getHeader("X-Custom-Header");
// 使用customValue...
return "viewName";
}
使用ClientHttpRequestInterceptor
实现ClientHttpRequestInterceptor
接口,可以在请求发送前动态添加或修改请求头。
public class CustomRequestHeaderInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
request.getHeaders().set("X-Custom-Request-Header", "DynamicValue");
return execution.execute(request, body);
}
}
使用Filter
通常,HTTP请求头是在客户端发送请求时设置的,一旦请求被发送到服务器,请求头就不能再被修改。Filter可以读取和修改HttpServletRequest对象,但它不能修改已经接收到的请求头,因为HTTP协议本身不支持修改请求头。如果你需要在服务器端“伪造”或“添加”请求头,这通常是通过在Filter中设置属性到HttpServletRequest中实现的,但这些属性不会成为HTTP请求头的一部分,它们仅可以被下游的Servlet或控制器方法所使用。
public class CustomRequestHeaderFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
httpRequest.setAttribute("X-Custom-Header", "HeaderValue");
chain.doFilter(request, response);
}
}
使用RestTemplate自定义请求
如果你在控制器中使用RestTemplate
发起请求,可以在请求头中动态设置值。
HttpHeaders headers = new HttpHeaders();
headers.set("X-Custom-Request-Header", dynamicHeaderValue);
HttpEntity<String> entity = new HttpEntity<>("Request Body", headers);
restTemplate.exchange(...);
设置响应头
使用@ResponseHeader注解
在控制器类或方法上使用@ResponseHeader
注解直接添加响应头。
@Controller
@ResponseHeader("X-Custom-Response-Header: DynamicValue")
public class ExampleController {
// 控制器方法...
}
使用HttpServletResponse
通过注入HttpServletResponse
对象,在控制器方法中调用setHeader
或addHeader
方法来设置响应头。
@RequestMapping("/example")
public String handleRequest(HttpServletResponse response) {
response.setHeader("X-Custom-Response-Header", "DynamicValue");
return "viewName";
}
使用ResponseEntity对象
返回一个ResponseEntity
对象,允许你设置状态码、头部和响应体。
@RequestMapping("/example")
public ResponseEntity<String> handleRequest() {
HttpHeaders headers = new HttpHeaders();
headers.set("X-Custom-Response-Header", "DynamicValue");
return new ResponseEntity<>("Response Body", headers, HttpStatus.OK);
}
使用HandlerInterceptor
实现HandlerInterceptor
接口,可以在请求处理后动态添加响应头。
public class CustomResponseHeaderInterceptor implements HandlerInterceptor {
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
response.setHeader("X-Custom-Response-Header", "DynamicValue");
}
}
使用Filter
创建一个过滤器,在请求处理之后动态设置响应头。
public class CustomHeaderFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(servletRequest, servletResponse);
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setHeader("X-Custom-Response-Header", "DynamicValue");
}
}
使用RestClient响应式调用
如果你使用响应式编程,可以在调用外部服务时动态设置响应头。
public Mono<ResponseEntity<String>> callExternalService(Data data) {
return webClient.post()
.uri("/example")
.header("X-Custom-Response-Header", dynamicHeaderValue)
.retrieve()
.bodyToMono(String.class);
}
说明
这些方法可以根据你的具体需求和场景灵活使用,例如是否需要在请求处理的特定阶段添加头部,或者是否需要全局地添加头部。