gpt4 book ai didi

java - 我可以强制在 Spring 中包含至少两个 header 之一吗?

转载 作者:行者123 更新时间:2023-12-02 09:36:22 26 4
gpt4 key购买 nike

我的一个标题拼写错误,我想在向后兼容的同时更改它。

@RequestHeader(value = "Custmer-Key") String customerKey

我想添加一个拼写正确的 header Customer-Key,并至少将其中之一设为强制。有什么想法吗?

最佳答案

我将在这里做出一些假设。每个解决方案在您的具体情况下可能正确,也可能不正确,但目的是提供更好的背景信息,说明此类解决方案何时可行且使用有意义。

  1. 您需要保持向后兼容性(这个很简单......您写的)
  2. 您有一个相当大的代码库,可能基于微服务并由多个开发人员维护,并且您希望避免跨多个团队进行大规模提交,将修复集中在所有服务都应使用的通用共享库中
  3. 您的 header 不仅使用 Spring 获取,有时也通过直接访问请求来获取
  4. 您正在开发一个生产应用程序,您希望尽可能少地更改代码,因为它的一些内部工作原理很难理解

该解决方案包括连接自定义过滤器及其配置。过滤器会将 HttpServletRequest 实例替换为允许操作 header 的不同实例。

<小时/>

首先,创建您自己的过滤器,如下所示:

import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class HeadersFilter implements Filter {

private static final String WRONG_HEADER = "Custmer-Key";
private static final String RIGHT_HEADER = "Customer-Key";

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

HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;

String newHeaderValue = request.getHeader(RIGHT_HEADER);
String headerValue;
if(newHeaderValue != null) {
headerValue = newHeaderValue;
}
else {
headerValue = request.getHeader(WRONG_HEADER);
}

HeadersRewriteHttpServletRequestWrapper requestWrapper = new HeadersRewriteHttpServletRequestWrapper(request);
requestWrapper.setCustomHeader(WRONG_HEADER, headerValue);

filterChain.doFilter(requestWrapper, response);
}

public static class HeadersRewriteHttpServletRequestWrapper extends HttpServletRequestWrapper {

private Map<String, String> customHeaders;

HeadersRewriteHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
customHeaders = new HashMap<>();
}

void setCustomHeader(String name, String value) {
customHeaders.put(name, value);
}

private String getCustomHeader(String name) {
return customHeaders.get(name);
}

@Override
public String getHeader(String name) { // not needed by spring but useful if someone uses this method directly
String header = super.getHeader(name);
if(header != null) {
return header;
}
return getCustomHeader(name);
}

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

@Override
public Enumeration<String> getHeaders(String name) {
List<String> headers = Collections.list(super.getHeaders(name));
String customHeader = getCustomHeader(name);
if(headers.isEmpty() && customHeader != null) {
headers.add(customHeader);
}
return Collections.enumeration(headers);
}
}
}

其次,连接 Spring 配置以创建此过滤器的实例并根据需要注入(inject)它。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfiguration {
@Bean
public HeadersFilter headersFilterBean() {
return new HeadersFilter();
}
}

就是这样。假设您的应用程序没有阻止其工作的怪癖(在这种情况下,祝您调试顺利),此代码将获取 Customer-KeyCustomer-Key 的内容code>,优先考虑 Customer-Key 并将它们写入假的 Custmer-Key header 中。这样您就不必触摸任何 Controller ,它们应该继续透明地工作。

关于java - 我可以强制在 Spring 中包含至少两个 header 之一吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57476250/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com