Рубрики
Без рубрики

Рефакторинг ветвей из контроллеров Spring с помощью параметров

Существует менее известный способ указать, какой метод в контроллере Spring должен выполняться на основе… Помеченный как spring, java.

Существует менее известный способ указать, какой метод в контроллере Spring должен выполняться на основе отправленных ему параметров запроса.

Прежде чем узнать об этом, я бы использовал необязательные параметры и операторы if внутри одного и того же обработчика, что увеличивает сложность и снижает удобочитаемость. Например, здесь я возвращаю банковский счет, и есть два способа его поиска: Имя на счете и с помощью Номер счета

@RestController
@RequestMapping(value = "/accounts")
public class AccountController {
    private AccountService accountService;

    public AccountController(AccountService accountService) {
        this.accountService = accountService;
    }

    @RequestMapping(method = GET)
    public ResponseEntity searchForAccount(
            @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 ResponseEntity getAccountByAccountNumber(
            @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”