Hilikus Hilikus - 3 years ago 135
reST (reStructuredText) Question

Control @RestController availability programmatically

Is it possible to control a

@RestController
programmatically to enable it or disable it? I don't want to just write code in each
@RequestMapping
method to do some kind of
if (!enabled) { return 404Exception; }


I've seen this question but that works only at startup time. What I need is really something that would allow me to enable or disable the controller multiple times.

I've thought of different ways but don't know which are doable in spring.


  1. Actually control the container (jetty in my case) so requests to that particular endpoint are disabled

  2. Somehow control
    RequestMappingHandlerMapping
    since it seems to be that class that does the mapping between urls and controllers

  3. control the lifecycle of the
    @RestController
    component so that i can create it and destroy it at will, but then i'm not sure how to trigger the mapping to the endpoint


Answer Source

If the end result is that you want to respond with a 404 when you decide that a specific endpoint should be disabled then you could write an interceptor which checks whether your enabled condition is false and, if so, sets the response accordingly.

For example:

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

In Spring Boot, registering your own interceptor just involves implementing a WebMvcConfigurerAdapter. For example:

@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);
  }
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download