Spring 以编程方式控制@RestController的可用性

Spring 以编程方式控制@RestController的可用性,spring,rest,spring-mvc,spring-boot,spring-restcontroller,Spring,Rest,Spring Mvc,Spring Boot,Spring Restcontroller,是否可以通过编程方式控制@RestController以启用或禁用它?我不想只在每个@RequestMapping方法中编写代码,以便在(!enabled){return 404Exception;} 我见过,但这只在启动时起作用。我真正需要的是允许我多次启用或禁用控制器的东西 我想了不同的方法,但不知道哪种在春天是可行的 实际上控制容器(在我的例子中是jetty),所以对特定端点的请求被禁用 以某种方式控制RequestMappingHandlerMapping,因为似乎是那个类在URL和控制

是否可以通过编程方式控制
@RestController
以启用或禁用它?我不想只在每个
@RequestMapping
方法中编写代码,以便在(!enabled){return 404Exception;}

我见过,但这只在启动时起作用。我真正需要的是允许我多次启用或禁用控制器的东西

我想了不同的方法,但不知道哪种在春天是可行的

  • 实际上控制容器(在我的例子中是jetty),所以对特定端点的请求被禁用
  • 以某种方式控制
    RequestMappingHandlerMapping
    ,因为似乎是那个类在URL和控制器之间进行映射
  • 控制
    @RestController
    组件的生命周期,以便我可以随意创建和销毁它,但我不确定如何触发到端点的映射

  • 如果最终结果是,当您决定禁用某个特定端点时,希望使用404响应,那么您可以编写一个拦截器来检查您的启用条件是否为false,如果是,则相应地设置响应

    例如:

    @Component
    public class ConditionalRejectionInterceptor extends HandlerInterceptorAdapter {
    
        @Override
        public boolean preHandle(HttpServletRequest request,
                HttpServletResponse response, Object handler) throws Exception {
            String requestUri = request.getRequestURI();
            if (shouldReject(requestUri)) {
                response.setStatus(HttpStatus.NOT_FOUND.value());
                return false;
            }
            return super.preHandle(request, response, handler);
        }
    
        private boolean shouldReject(String requestUri) {
            // presumably you have some mechanism of inferring or discovering whether 
            // the endpoint represented by requestUri should be allowed or disallowed
            return ...;
        }
    }
    
    @Configuration
    public class CustomWebMvcConfigurer extends WebMvcConfigurerAdapter {
    
      @Autowired 
      private HandlerInterceptor conditionalRejectionInterceptor;
    
      @Override
      public void addInterceptors(InterceptorRegistry registry) {
        // you can use .addPathPatterns(...) here to limit this interceptor to specific endpoints
        // this could be used to replace any 'conditional on the value of requestUri' code in the interceptor
        registry.addInterceptor(conditionalRejectionInterceptor);
      }
    }
    
    在Spring Boot中,注册您自己的拦截器只需要实现一个
    WebMVCConfigureAdapter
    。例如:

    @Component
    public class ConditionalRejectionInterceptor extends HandlerInterceptorAdapter {
    
        @Override
        public boolean preHandle(HttpServletRequest request,
                HttpServletResponse response, Object handler) throws Exception {
            String requestUri = request.getRequestURI();
            if (shouldReject(requestUri)) {
                response.setStatus(HttpStatus.NOT_FOUND.value());
                return false;
            }
            return super.preHandle(request, response, handler);
        }
    
        private boolean shouldReject(String requestUri) {
            // presumably you have some mechanism of inferring or discovering whether 
            // the endpoint represented by requestUri should be allowed or disallowed
            return ...;
        }
    }
    
    @Configuration
    public class CustomWebMvcConfigurer extends WebMvcConfigurerAdapter {
    
      @Autowired 
      private HandlerInterceptor conditionalRejectionInterceptor;
    
      @Override
      public void addInterceptors(InterceptorRegistry registry) {
        // you can use .addPathPatterns(...) here to limit this interceptor to specific endpoints
        // this could be used to replace any 'conditional on the value of requestUri' code in the interceptor
        registry.addInterceptor(conditionalRejectionInterceptor);
      }
    }
    

    if(!enabled)
    逻辑可能比
    RequestMappingHandlerMapping
    的自定义实现简单得多。看看像Togglz这样的功能切换框架。这个怎么样?我想到了一些东西——拦截器(基于url路径)或ControllerAdvice(这可能更接近您想要的)。另外,也许您可以从DispatcherServlet开始戳,但我从未尝试过b4。您可以为端点添加筛选器:。检查其中的“enabled”属性并采取适当的行动。这几乎完美地工作了。我必须在“应该拒绝”中添加一个
    return false
    ,否则请求将沿着处理程序链继续