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

Control @RestController availability programmatically

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

我见过 但这只在启动时有效。我真正需要的是能让我多次启用或禁用控制器的东西。

我想过不同的方法,但不知道在 spring 中哪些是可行的。

  1. 实际控制容器(在我的例子中是码头),因此禁用对该特定端点的请求
  2. 以某种方式控制 RequestMappingHandlerMapping 因为它似乎是 class 在 url 和控制器之间进行映射
  3. 控制 @RestController 组件的生命周期,以便我可以随意创建和销毁它,但我不确定如何触发到端点的映射

如果最终结果是您想在决定应禁用特定端点时以 404 响应,那么您可以编写一个拦截器来检查您启用的条件是否为假,如果是,则设置响应因此。

例如:

@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 ...;
    }
}

在 Spring 引导中,注册您自己的拦截器只需要实现一个 WebMvcConfigurerAdapter。例如:

@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);
  }
}