【问题标题】:Spring Boot @RestController enable/disable methods using properties [duplicate]Spring Boot @RestController 使用属性启用/禁用方法[重复]
【发布时间】:2018-04-08 07:10:30
【问题描述】:

我可以使用@ConditionalOnProperty启用/禁用整个@RestController,例如:

@RestController
@ConditionalOnProperty(name = "com.example.api.controller.decision.DecisionController.enabled", havingValue = "true")
@RequestMapping("/v1.0/decisions")
public class DecisionController {
}

以下配置工作正常。但我需要对此控制器进行更细粒度的控制,并启用/禁用对内部某些方法的访问,例如:

@RestController
@ConditionalOnProperty(name = "com.example.api.controller.decision.DecisionController.enabled", havingValue = "true")
@RequestMapping("/v1.0/decisions")
public class DecisionController {

    @ConditionalOnProperty(name = "com.example.api.controller.decision.DecisionController.create.enabled", havingValue = "true")
    @PreAuthorize("isAuthenticated()")
    @RequestMapping(method = RequestMethod.POST)
    public DecisionResponse create(@Valid @RequestBody CreateDecisionRequest request, Authentication authentication) {
        ...
    }

}

如您所见,我已将@ConditionalOnProperty 添加到create 方法,但此方法不起作用,并且在启用DecisionController 的情况下,即使com.example.api.controller.decision.DecisionController.create.enabled 属性不存在,create 方法也会启用在我的application.properties

在这种情况下如何正确启用/禁用create 方法?

【问题讨论】:

  • 只是好奇:用例是什么?为什么要禁用某些方法?
  • @JBNizet 我有定义核心端点和方法的核心项目(Maven 模块)。另外,我有项目特定的 Maven 子模块,其中包括提到的核心模块作为依赖项。根据我的子模块项目中的业务需求和配置,我需要隐藏一些继承自核心项目的核心功能(一些方法)。现在我可以隐藏整个控制器,但我需要更细粒度的控制。
  • 最简单的方法可能是使用过滤器,并拦截对某些 URL/HTTP 方法的请求,如果它们被禁用则返回 404。

标签: java spring spring-boot application-settings


【解决方案1】:

您也可以使用 aop 不继续执行方法并将某些状态返回给用户。 我在这里使用注释来标记/识别禁用的方法。如果要根据属性中的某些值禁用,可以向该注释添加属性。就像您可以添加相同的属性名称和具有值并查找这些等等...

@Retention(RUNTIME)
@Target(METHOD)
public @interface DisableMe {}

方面:

@Aspect
@Component
public class DisableCertainAPI {

  @Autowired private HttpServletResponse httpServletResponse;

  @Pointcut(" @annotation(disableMe)")
  protected void disabledMethods(DisableMe disableMe) {
    // disabled methods pointcut
  }

  @Around("disabledMethods(disableMe)")
  public void dontRun(JoinPoint jp, DisableMe disableMe) throws IOException {
    httpServletResponse.sendError(HttpStatus.NOT_FOUND.value(), "Not found");
  }
}

关于目标方法:

 @DisableMe
 @GetMapping(...)
 public ResponseEntity<String> doSomething(...){
  logger.info("recieved a request");
 }

您会看到如下响应:

{
  "timestamp": "2019-11-11T16:29:31.454+0000",
  "status": 404,
  "error": "Not Found",
  "message": "Not found",
  "path": "/xyz/...."
}

【讨论】:

    【解决方案2】:

    不幸的是,@ConditionalOnProperty 注解不能用于单个@RequestMapping 方法。作为一种解决方法,您可以将所需的映射移动到单独的控制器 bean。

    http://dolszewski.com/spring/feature-toggle-spring-boot/

    我希望这个可以帮助到这个页面的人通过同样的问题。

    【讨论】:

      猜你喜欢
      • 2015-07-09
      • 1970-01-01
      • 2014-02-14
      • 2016-07-25
      • 2016-05-10
      • 2019-03-30
      • 2021-12-24
      • 1970-01-01
      • 2016-07-16
      相关资源
      最近更新 更多