从@RestControllerAdvice 中的@ModelAttribute 中排除方法

Exclude methods from @ModelAttribute in @RestControllerAdvice

我有以下控制器:

@RestController
@RequestMapping("/api/{brand}"
public class CarController {

  @GetMapping
  public List<Car> getCars(@PathVariable("brand") String brand) {
    // Some implementation
  }

  @GetMapping("/{model}")
  public Car getCar(@PathVariable("model") String model) {
    // Some implementation
  }

  @PostMapping("/{model}")
  public Car addCar(@PathVariable("model") String model), @RequestBody Car car) {
    // Some implementation
  }
}

以及以下RestControllerAdvice

@RestControllerAdvice(assignableTypes = {CarController.class})
public class InterceptModelPathParameterControllerAdvice {

  @Autowired
  CarService carService;

  @ModelAttribute
  public void validateModel(@PathVariable("model") String model) {
    if (!carService.isSupportedModel(model)) throw new RuntimeException("This model is not supprted by this application.");
  }
}

validateModel 正确验证了 getCaraddCar 方法,但它也验证了 getCars 方法。 getCars 方法没有 {model} @PathVariable,因此对此端点的请求将始终导致 RuntimeException

有什么方法可以排除方法受到 ControllerAdviceModelAttribute 组合的影响吗?

据我所知,没有真正的方法可以排除方法被@ControllerAdvice中的@ModelAttribute拦截。但是,您可以将方法参数从 @PathVariable("model") String model 更改为 HttpServletRequest request 并按如下方式更改实现:

@ModelAttribute
public void validateModel(HttpServletRequest) {
  Map<String, String> requestAttributes = (Map<String, String>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
  if (requestAttributes.containsKey("model") {
    String model = requestAttributes.get("model");
    if (!carService.isSupportedModel(model)) throw new RuntimeException("This model is not supprted by this application.");
  }
}