【问题标题】:Spring: Checking if given endpoint existsSpring:检查给定端点是否存在
【发布时间】:2015-09-15 11:35:38
【问题描述】:

就像标题一样。我想知道,是否有简单的方法来检查给定路径是否可以转换为任何控制器中存在的(API)端点。

我有一个具有最高优先级的自定义过滤器,如果给定的请求不会产生任何结果(端点不存在),我想返回 404 状态代码。

【问题讨论】:

  • 您是在为服务创建客户端还是在托管服务并希望在处理请求之前检查自己的端点?
  • @KevinBayes 第二个。我正在添加一个过滤器,我想在其中检查端点是否存在(如果不存在则发送 404,发送其他状态代码或继续过滤器链)
  • 好的,我添加了一个示例,说明我将如何使用 Spring Boot 进行操作。

标签: java spring spring-boot


【解决方案1】:

为此,您需要创建一个将 RequestMappingHandlerMapping 作为属性的过滤器。像这样的:

 public class AllHandlersList extends OncePerRequestFilter {

    RequestMappingHandlerMapping requestMappingHandlerMapping;

    public AllHandlersList(RequestMappingHandlerMapping requestMappingHandlerMapping) {
        this.requestMappingHandlerMapping = requestMappingHandlerMapping;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try {
            //Add you own logic here ot handle the request your way. 
            System.out.println(requestMappingHandlerMapping.getHandler(request).getHandler());
        } catch (Exception e) {
            e.printStackTrace();
        }
        filterChain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }
}

然后你需要注册它。我看到您使用 Spring Boot,因此您可以将其添加到您的 Java 配置中:

    @Bean
    @Autowired
    public FilterRegistrationBean listHandlers(RequestMappingHandlerMapping requestMappingHandlerMapping) {
        FilterRegistrationBean register = new FilterRegistrationBean();
        register.setFilter(new AllHandlersList(requestMappingHandlerMapping));
        register.setName("handlerListFilter");
        register.setUrlPatterns(Arrays.asList(new String[]{"/"}));
        register.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return register;
    }

参考资料: API 文档 http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.html

春季发行说明 http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-ann-requestmapping-31-vs-30

【讨论】:

    【解决方案2】:

    看看RequestMappingHandlerMapping 类,尤其是它的getHandlerMethods 方法。

    来自文档:

    public Map<T,HandlerMethod> getHandlerMethods()

    返回一个包含所有映射和 HandlerMethod 的(只读)映射。

    对于RequestMappingHandlerMappingTRequestMappingInfo

    来自RequestMappingInfo docs

    封装了如下请求映射条件:

    1. 模式请求条件
    2. RequestMethodsRequestCondition
    3. ParamsRequestCondition
    4. HeadersRequestCondition
    5. ConsumesRequestCondition
    6. 产生请求条件
    7. RequestCondition(可选,自定义请求条件)

    来自HandlerMethod docs

    封装有关由方法和 bean 组成的处理程序方法的信息。提供对方法参数、方法返回值、方法注解的便捷访问。


    如果您想从过滤器 bean 执行此操作,您可以将 RequestMappingHandlerMapping bean 自动连接到它:

    @Component
    public class MyFilterBean extends OncePerRequestFilter {
    
        @Autowired
        RequestMappingHandlerMapping mappings;
    
    }
    

    【讨论】:

    • 请问如何从 Filter/OncePerRequestFilter 类中获取这些?
    • @TrynkiewiczMariusz 当然,只需自动连接RequestMappingHandlerMapping。我将编辑我的答案。
    猜你喜欢
    • 2017-04-04
    • 2016-01-25
    • 2018-09-10
    • 2017-06-03
    • 2021-09-19
    • 1970-01-01
    • 2014-10-21
    • 2017-02-26
    • 2012-02-27
    相关资源
    最近更新 更多