默认情况下如何在Spring Boot REST中执行最新版本的端点?



我正在使用自定义标头开发Spring Boot v2.2.2.RELEASE和API版本控制。默认情况下,我希望执行最新版本的端点。

在下面的代码中,它的X-API-VERSION=2.在执行端点之前,我需要检查映射,然后为自定义标头设置最新版本,然后执行它。

@GetMapping(value = "/student/header", headers = {"X-API-VERSION=1"})
public StudentV1 headerV1() {
return serviceImpl.headerV1();
}
@GetMapping(value = "/student/header", headers = {"X-API-VERSION=2"})
public StudentV1 headerV2() {
return serviceImpl.headerV2();
}

如果我的问题是正确的,您希望没有X-API-VERSION标头的请求将自动路由到headerV2()方法

这可以做到:

从概念上讲,你需要一个在Spring MVC Dispatch Servlet之前执行的Web过滤器,你必须检查请求是否包含一个标头,以及它是否没有添加你认为应该是最新版本的版本标头(来自配置或其他内容(。

这里需要注意的是,HttpServletRequest 不允许添加标头,因此您必须创建一个 HttpServletRequestWrapper 并在那里实现标头添加逻辑。

下面是一个例子(我借用了这个问题的实现(:

// The web filter 
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
@Component
@Order(1)
public class LatestVersionFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
if(req.getHeader("X-API-VERSION")== null) {
HeaderMapRequestWrapper wrappedRequest = new HeaderMapRequestWrapper(req);
wrappedRequest.addHeader("X-API-VERSION", resolveLastVersion());
filterChain.doFilter(wrappedRequest, servletResponse);
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
}
private String resolveLastVersion() {
// read from configuration or something
return "2";
}
}

请注意,请求被包装以添加标头,如我所解释的那样:

class HeaderMapRequestWrapper extends HttpServletRequestWrapper {
/**
* construct a wrapper for this request
*
* @param request
*/
public HeaderMapRequestWrapper(HttpServletRequest request) {
super(request);
}
private Map<String, String> headerMap = new HashMap<String, String>();
/**
* add a header with given name and value
*
* @param name
* @param value
*/
public void addHeader(String name, String value) {
headerMap.put(name, value);
}
@Override
public String getHeader(String name) {
String headerValue = super.getHeader(name);
if (headerMap.containsKey(name)) {
headerValue = headerMap.get(name);
}
return headerValue;
}
/**
* get the Header names
*/
@Override
public Enumeration<String> getHeaderNames() {
List<String> names = Collections.list(super.getHeaderNames());
for (String name : headerMap.keySet()) {
names.add(name);
}
return Collections.enumeration(names);
}
@Override
public Enumeration<String> getHeaders(String name) {
List<String> values = Collections.list(super.getHeaders(name));
if (headerMap.containsKey(name)) {
values.add(headerMap.get(name));
}
return Collections.enumeration(values);
}
}

通过此实现(确保将 servlet 放在包中控制器或其他东西旁边,以便 Spring 引导将其识别为组件(,您将看到:

  1. 带有标头X-API-VERSION=1的 GET 将被路由到headerV1()
  2. 带有标头X-API-VERSION=2的 GET 将被路由到headerV2()
  3. 没有X-API-VERSION标头的 GET 将被路由到headerV2()

您可以添加不带标头的默认方法,如下所示:

@GetMapping(value = "/student/header")
public StudentV1 headerDefault() {
return headerV2();
}

或者只是从应该是最新的方法中删除headers = {"X-API-VERSION=2"}

相关内容

  • 没有找到相关文章

最新更新