【问题标题】:Control @RestController availability programmatically以编程方式控制 @RestController 可用性
【发布时间】:2018-01-31 10:50:57
【问题描述】:

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

我见过this question,但这仅在启动时有效。我真正需要的是允许我多次启用或禁用控制器的东西。

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

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

【问题讨论】:

  • if(!enabled) 逻辑可能比RequestMappingHandlerMapping 的自定义实现简单得多。看看像 Togglz 这样的功能切换框架。
  • 我想到了一些事情——拦截器(基于 url 路径)或 ControllerAdvice(这可能更接近你想要的)。另外,也许你可以从 DispatcherServlet 开始,但我从未尝试过 b4。
  • 您可以为您的端点添加过滤器:stackoverflow.com/questions/19825946/…。检查其中的“启用”属性并采取适当的行动。

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


【解决方案1】:

如果最终结果是当您决定应该禁用特定端点时想要以 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 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);
  }
}

【讨论】:

  • 这工作几乎完美。我必须在应该拒绝中添加一个return false,否则请求会沿着处理程序链继续下去
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-26
  • 2011-07-09
  • 1970-01-01
  • 2011-12-09
  • 2022-07-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多