在Spring Boot中将自定义标头注入到ServletRequest

huangapple go评论142阅读模式
英文:

Injecting custom headers into ServletRequest in Spring Boot JAVA

问题

以下是您提供的内容的翻译:

我有一个要求,需要在每个Spring Boot应用程序收到的每个请求中注入自定义标头。为此,我编写了一些代码,但似乎并没有起作用。简要地说,我实现了Filter接口并定义了doFilter方法,扩展了HttpServletRequestWrapper类,并重写了getHeader()和getHeaderNames()方法,以考虑从属性文件中读取的自定义标头。

但是,当我进入控制器并检查请求时,我没有收到通过MyReqWrapper设置的自定义标头。以下是代码,我还尝试在Stackoverflow上搜索,但找不到关于这里出了什么问题的解决方案。有人可以指点我正确的方向吗?

另外,请告诉我如何测试自定义标头是否实际设置了。

这是过滤器实现

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ReqFilter implements Filter {
    private static final String CUSTOMHEADERENABLED = "customheadersenabled";
    private static final String CUSTOMHEADERCOUNT = "customheaderscount";
    
    @Autowired
    private Environment env;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        try {
            boolean customHeadersEnabled = Boolean.parseBoolean(env.getProperty(CUSTOMHEADERENABLED, "false"));
            int count = Integer.parseInt(env.getProperty(CUSTOMHEADERCOUNT, "0"));

            if (customHeadersEnabled && count > 0) {
                MyReqWrapper myReq = new MyReqWrapper((HttpServletRequest) servletRequest);
                myReq.processMyHeaders(count, env);
                filterChain.doFilter(customRequest, servletResponse);
            } else {
                filterChain.doFilter(servletRequest, servletResponse);
            }
        }
        catch(ServletException ex){
            throw ex;
        }
    }

    @Override
    public void destroy() {
        //
    }
}

这是扩展HttpServletRequestWrapper的自定义请求包装器

final class MyReqWrapper extends HttpServletRequestWrapper {
    private static final String CUSTOMHEADERPREFIX = "header1";
    private final Map<String, String> myHeaders;

    public MyReqWrapper(HttpServletRequest request) {
        super(request);
        myHeaders = new HashMap<>();
    }

    @Override
    public String getHeader(String name) {
        String headerValue = myHeaders.get(name);

        if (headerValue != null){
            return headerValue;
        }
        return ((HttpServletRequest) getRequest()).getHeader(name);
    }

    @Override
    public Enumeration<String> getHeaderNames() {
        Set<String> set = new HashSet<>(myHeaders.keySet());

        Enumeration<String> headerNames = ((HttpServletRequest) getRequest()).getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String n = headerNames.nextElement();
            set.add(n);
        }
        return Collections.enumeration(set);
    }

    public void processMyHeaders(int headerCount, Environment env) {
        while(headerCount > 0){
            String [] headerKeyValue = Objects.requireNonNull(env.getProperty(String.format("%1$s%2$s", CUSTOMHEADERPREFIX, headerCount--)))
                    .split(":");
            this.myHeaders.put(headerKeyValue[0], headerKeyValue[1]);
        }
    }
}

如果您有任何进一步的问题或需要解释,请随时提问。

英文:

I have a requirement to inject custom headers into every request a spring boot application is getting, for this, I have written some code but it seems it is not doing its work. For a brief, I have implemented the Filter interface and defined the doFilter method, extended the HttpServletRequestWrapper class, and overridden getHeader() and getHeaderNames() method to take into account the custom headers I am reading from the properties file.

But, the moment I get into the controller and check the request I am not getting my custom headers that were set through the MyReqWrapper. Below is the code, I've also tried searching it in Stackoverflow but couldn't find the solution on what is/could be wrong here. Can someone point me in the right direction?

Also, please point me on how to test whether custom headers are actually set or not.

This is Filter implementation

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ReqFilter implements Filter {
private static final String CUSTOMHEADERENABLED = &quot;customheadersenabled&quot;;
private static final String CUSTOMHEADERCOUNT = &quot;customheaderscount&quot;;
@Autowired
private Environment env;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
try {
boolean customHeadersEnabled = Boolean.parseBoolean(env.getProperty(CUSTOMHEADERENABLED, &quot;false&quot;));
int count = Integer.parseInt(env.getProperty(CUSTOMHEADERCOUNT, &quot;0&quot;));
if (customHeadersEnabled &amp;&amp; count &gt; 0) {
MyReqWrapper myReq = new MyReqWrapper((HttpServletRequest) servletRequest);
myReq.processMyHeaders(count, env);
filterChain.doFilter(customRequest, servletResponse);
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
}
catch(ServletException ex){
throw ex;
}
}
@Override
public void destroy() {
//
}
}

This is custom request wrapper extending HttpServletRequestWrapper

final class MyReqWrapper extends HttpServletRequestWrapper {
private static final String CUSTOMHEADERPREFIX = &quot;header1&quot;;
private final Map&lt;String, String&gt; myHeaders;
public MyReqWrapper(HttpServletRequest request) {
super(request);
myHeaders = new HashMap&lt;&gt;();
}
@Override
public String getHeader(String name) {
String headerValue = myHeaders.get(name);
if (headerValue != null){
return headerValue;
}
return ((HttpServletRequest) getRequest()).getHeader(name);
}
@Override
public Enumeration&lt;String&gt; getHeaderNames() {
Set&lt;String&gt; set = new HashSet&lt;&gt;(myHeaders.keySet());
Enumeration&lt;String&gt; headerNames = ((HttpServletRequest) getRequest()).getHeaderNames();
while (headerNames.hasMoreElements()) {
String n = headerNames.nextElement();
set.add(n);
}
return Collections.enumeration(set);
}
public void processMyHeaders(int headerCount, Environment env) {
while(headerCount &gt; 0){
String [] headerKeyValue = Objects.requireNonNull(env.getProperty(String.format(&quot;%1$s%2$s&quot;, CUSTOMHEADERPREFIX, headerCount--)))
.split(&quot;:&quot;);
this.myHeaders.put(headerKeyValue[0], headerKeyValue[1]);
}
}
}

答案1

得分: 0

这个问题已经为我解决了,但是我忘记更新答案。

所以问题是在ReqFilter和控制器类中我使用了来自两个不同命名空间的HttpServletRequest类,一个来自于**"org.apache.catalina.servlet4preview.http.HttpServletRequest",另一个来自于"javax.servlet.http.HttpServletRequest"**。

一旦我在这两个文件中使用了统一的命名空间,我就可以从控制器类中访问头部信息。

英文:

This was solved for me and I forgot to update this with an answer.

So the problem was I was using HttpServletRequest class from two different namespaces in the ReqFilter and controller classes, namely one from "org.apache.catalina.servlet4preview.http.HttpServletRequest" and another from "javax.servlet.http.HttpServletRequest".

Once I used uniform namespace in both the files I could access the headers from controller classes.

huangapple
  • 本文由 发表于 2020年7月24日 18:46:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/63072006.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定