Существует менее известный способ указать, какой метод в контроллере Spring должен выполняться на основе отправленных ему параметров запроса.
Прежде чем узнать об этом, я бы использовал необязательные параметры и операторы if внутри одного и того же обработчика, что увеличивает сложность и снижает удобочитаемость. Например, здесь я возвращаю банковский счет, и есть два способа его поиска: Имя на счете
и с помощью Номер счета
@RestController @RequestMapping(value = "/accounts") public class AccountController { private AccountService accountService; public AccountController(AccountService accountService) { this.accountService = accountService; } @RequestMapping(method = GET) public ResponseEntitysearchForAccount( @RequestParam(value = "accountNumber", required = false) String accountNumber, @RequestParam(value = "nameOnAccount", required = false) String nameOnAccount) { // both params are optional so I need to manually check if neither or both exist if ((isBlank(accountNumber) && isBlank(nameOnAccount)) || isNotBlank(accountNumber) && isNotBlank(nameOnAccount)) { // Returns a bad request throw new AccountSearchException( "Must provide either account number or name on account only."); } if (isNotBlank(accountNumber)) { return accountService.getAccountByAccountNumber(accountNumber); } else { return accountService.getAccountByNameOnAccount(nameOnAccount); } } }
Приведенный выше метод содержит больше инструкций if, чем необходимо для простого обработчика, что затрудняет его чтение. Мы можем упростить это, используя поле params в аннотации @RequestMapping
.
Вы можете указать массив строк в поле параметров @RequestMapping
. В этом поле можно указать, должны ли параметры запроса запроса иметь определенное значение, например params
или не имеют определенного значения например params
или должен ли параметр запроса иметь какое-либо значение, например params
или отсутствует , например параметры/| .
Приведенный ниже пример показывает, как вы можете упростить приведенный выше код и при этом обеспечить ту же функциональность. Другой возможный параметр необходимо отрицать, чтобы, если кто-то предоставит оба параметра запроса, он получил обратно код состояния 400, как и раньше из AccountSearchException
.
@RestController @RequestMapping(value = "/accounts") public class AccountController { private AccountService accountService; public AccountController(AccountService accountService) { this.accountService = accountService; } @RequestMapping(method = GET, params = {"accountNumber", "!nameOnAccount" }) public ResponseEntitygetAccountByAccountNumber( @RequestParam(value = "accountNumber") String accountNumber) { return accountService.getAccountByAccountNumber(accountNumber); } @RequestMapping(method = GET, params = {"nameOnAccount", "!accountNumber"}) public ResponseEntity getAccountByNameOnAccount( @RequestParam(value = "nameOnAccount") String nameOnAccount) { return accountService.getAccountByNameOnAccount(nameOnAccount); } }
Используя поле params, мы смогли избавиться от ряда ветвей в нашем коде, сохраняя при этом обработчики, привязанные к одному и тому же сопоставлению URL.
Оригинал: “https://dev.to/philhardwick/refactoring-branches-out-of-spring-controllers-with-params-1b55”