Spring Boot @RestController使用属性启用/禁用方法

2020年8月28日 55点热度 0条评论

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

@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,即使我的
create中没有
com.example.api.controller.decision.DecisionController.create.enabled属性,也会启用
application.properties方法。

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

解决方案如下:

您还可以使用aop停止执行方法,并向用户返回一些状态。
我在这里使用注释来标记/识别禁用的方法。如果要基于属性中的某些值禁用该属性,则可以向该注释添加属性。就像您可以添加相同的属性名称和havingvalue并查找那些属性,依此类推...

@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/...."
}