You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从application.properties读取值并设置为@RequestHeader默认值

解决方案:通过HttpServletRequestWrapper + Filter实现请求头默认值注入

要实现从application.properties读取配置作为请求头的默认值,核心思路是在请求到达Controller之前,通过Filter包装HttpServletRequest,注入默认的请求头值,具体步骤如下:

1. 创建可变请求头的HttpServletRequest包装类

继承HttpServletRequestWrapper,重写请求头相关方法,实现自定义的请求头存储逻辑:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.*;

public class MutableHttpServletRequest extends HttpServletRequestWrapper {
    private final Map<String, String> customHeaders;

    public MutableHttpServletRequest(HttpServletRequest request) {
        super(request);
        this.customHeaders = new HashMap<>();
    }

    // 添加自定义请求头
    public void putHeader(String name, String value) {
        this.customHeaders.put(name, value);
    }

    @Override
    public String getHeader(String name) {
        // 优先取自定义的请求头,没有的话再取原生请求头
        String headerValue = customHeaders.get(name);
        if (headerValue != null) {
            return headerValue;
        }
        return ((HttpServletRequest) getRequest()).getHeader(name);
    }

    @Override
    public Enumeration<String> getHeaders(String name) {
        List<String> headers = new ArrayList<>(Collections.list(((HttpServletRequest) getRequest()).getHeaders(name)));
        String customHeader = customHeaders.get(name);
        if (customHeader != null) {
            headers.add(customHeader);
        }
        return Collections.enumeration(headers);
    }

    @Override
    public Enumeration<String> getHeaderNames() {
        Set<String> headerNames = new HashSet<>(Collections.list(((HttpServletRequest) getRequest()).getHeaderNames()));
        headerNames.addAll(customHeaders.keySet());
        return Collections.enumeration(headerNames);
    }
}

2. 创建Filter处理请求头注入

在Filter中读取配置文件的值,判断请求是否携带目标请求头,若没有则通过包装类注入默认值:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@Component
public class DefaultHeaderFilter implements Filter {

    @Value("${item.includePrice.value}")
    private String defaultIncludePrice;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(httpRequest);

        // 检查请求是否携带includePrice,没有则注入默认值
        String includePrice = httpRequest.getHeader("includePrice");
        if (includePrice == null || includePrice.isEmpty()) {
            mutableRequest.putHeader("includePrice", defaultIncludePrice);
        }

        // 传递包装后的请求到后续流程
        chain.doFilter(mutableRequest, response);
    }

    // 初始化和销毁方法可留空
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void destroy() {}
}

3. 配置Filter拦截路径(可选,若需指定拦截范围)

如果需要只拦截特定路径的请求,可以通过FilterRegistrationBean注册Filter:

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<DefaultHeaderFilter> defaultHeaderFilterRegistration(DefaultHeaderFilter filter) {
        FilterRegistrationBean<DefaultHeaderFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(filter);
        // 指定拦截的API路径,比如只拦截/item开头的请求
        registrationBean.addUrlPatterns("/item/*");
        return registrationBean;
    }
}

4. 修改Controller代码

此时请求中一定会包含includePrice请求头(要么是客户端传递的,要么是Filter注入的默认值),可以简化Controller的判断逻辑:

@PostMapping("/item")
public String postBody(@RequestHeader String includePrice, @RequestBody SomeRequest someRequest) {
    // 无需再判断includePrice是否为null
    return "You searched for " + someRequest.getItemName();
}

为什么拦截器方案不可行?

原生的HttpServletRequest并没有提供修改请求头的方法,拦截器只能读取请求头,无法修改;而Filter可以在请求进入Servlet容器的早期阶段,通过包装HttpServletRequest替换成自定义的实现,从而实现请求头的修改和注入。

内容的提问来源于stack exchange,提问作者psprogrammer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 22:40:23