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

时间:2017-08-23 02:29:00

标签: spring rest spring-mvc spring-boot spring-restcontroller

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

我已经看过this question,但仅在启动时有效。我需要的是能让我多次启用或禁用控制器的东西。

我想过不同的方法,但不知道春天哪些是可行的。

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

1 个答案:

答案 0 :(得分:1)

如果最终结果是您希望在确定应禁用特定端点时使用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 ...;
    }
}

在Spring Boot中,注册自己的拦截器只需要实现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);
  }
}