我们如何监听任何在 Spring 中没有标记@RestController注释的 URL/端点?



有没有办法我可以监听任何特定的请求,而该请求不会出现在 Spring 中的任何请求映射中?我正在尝试构建一个网关功能,我需要通过检查请求 URI 将请求重定向到下游 API。我需要查看我是否有该特定请求的下游/内部 api,如果我有该映射,则转发到下游 API。

我目前在数据库中拥有所有下游映射。

例如:

面向客户端的 uri: http://external_host/api/xyz/

下游 URI:http://downstream_host/api/abc

我将面向客户端的 uri 和下游 uri 的映射存储在数据库中。因此,我只想侦听命中我的服务的所有请求,然后根据我存储的映射自行检查是否可以转发请求。

我所能想到的就是拥有一个可以接受任何请求的控制器,但我不喜欢这种方法,因为这似乎很幼稚。

@RestController
@RequestMapping(value = "*")
public class TestController {
@RequestMapping(value = "/*", method = RequestMethod.GET)
public void GetRequestUri() {
System.out.println("test");
}
}

我希望我的问题足够详细。

您可以使用Netflix Zuul,这是一个执行路由和过滤的代理,但方式不同。

如果要构建自己的代理 - 发现服务,则只需要使用一个终结点,因此您的实现没有任何错误!

方法 - 创建过滤器

参考:如何在Spring MVC中注册一个servlet过滤器

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class RootFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
// Evaluate the request path
chain.doFilter(request, response);
} catch (Exception ex) {
//handle Exceptions.
}
}
}

网络.xml

<filter>
<filter-name>RootFilter</filter-name>
<filter-class>com.....RootFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>RootFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

public class MyWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Filter[] getServletFilters() {
return new Filter[]{new RootFilter()};
}
}

方法 - 创建拦截器

参考:Spring 3 MVC 拦截器教程

Spring MVC提供了一个强大的机制来拦截http请求。与 Servlet Filter 概念类似,Spring MVC 提供了一种定义称为拦截器的特殊类的方法,该类在请求被处理之前和之后被调用。

您定义的每个侦听器都必须实现org.springframework.web.servlet.HandlerInterceptor接口。需要实现三种方法。

preHandle(..)在执行实际处理程序之前调用

;preHandle(..) 方法返回一个布尔值。可以使用此方法中断或继续处理执行链。当此方法返回 true 时,处理程序执行链将继续;当它返回 false 时,DispatcherServlet 假定拦截器本身已经处理了请求(例如,呈现了适当的视图),并且不会继续执行执行链中的其他拦截器和实际处理程序。

postHandle(..)在处理程序执行后调用;

afterCompletion(..)在完成请求后调用。

这三种方法应该提供足够的灵活性来进行各种预处理和后处理。

最新更新