Как фильтровать по модели вместо нескольких параметров при весенней загрузке - PullRequest
0 голосов
/ 05 июля 2018

У меня есть конечная точка, которая перечисляет объекты и запрашивает ее по параметрам запроса, которые мы добавляем. Некоторые значения не являются обязательными. Когда количество фильтрующих значений растет, код выглядит ужаснее. Я ищу решение, которое также выглядит хорошо.

http://localhost:port/v1/actions?type=1&from=x&to=y&userId=z&adminId

И вместо того, чтобы иметь много параметров в моем контроллере, как:

@RequestMapping(value = "/action")
  public List<Actions> get(@RequestParam(value = "type") Optional<ActionType> actionType,
                             @RequestParam(value = "from") @DateTimeFormat(pattern = "MMddyyyy") Optional<Date> from,
                             @RequestParam(value = "to") @DateTimeFormat(pattern = "MMddyyyy") Optional<Date> to,
                             @RequestParam(value = "userId") Optional<UUID> userId,
                             @RequestParam(value = "adminId") UUID adminId) {
    return handler.getActions(type, from, to, userId, adminId);

Не удалось найти решение. Может быть, что-то подобное было бы круто. Наличие модели и аннотирование их, как будут называться параметры запроса:

public class QueryObject {
    @RequestParam(value = "type") Optional<ActionType> type;
    @RequestParam(value = "from") @DateTimeFormat(pattern = "MMddyyyy") Optional<Date> from;
    @RequestParam(value = "to") @DateTimeFormat(pattern = "MMddyyyy") Optional<Date> to;
     @RequestParam(value = "userId") Optional<UUID> userId;
     @RequestParam(value = "adminId") UUID adminId;

    //Getters and setters
    ...
}

Нечто подобное было бы круто:

@RequestMapping(value = "/action")
public List<actions> get(
    QueryObject object,
    ) { return handler.getActions(object); }

Если у вас есть предложения? Возможно ли это сделать?

1 Ответ

0 голосов
/ 12 июля 2018

Такие ситуации довольно распространены. Таким образом, всегда лучше иметь только один параметр запроса, который будет принимать строковое значение в форме "key1::value1|key2::value2|key3::value3| .... Затем для метода контроллера напишите синтаксический анализатор, который сгенерирует карту параметров (ключей) вашего запроса и их значений. рекомендуется обрабатывать параметры запроса.

Вот пример:

@RequestMapping(method = RequestMethod.GET, path="/search-products")
public ProductInfoListResponse searchProducts(@RequestParam(name = "filter", required = false) String filter) {

            final String[] QUERY_FILTER_KEYS = { "name", "type", "minCostPrice", "maxCostPrice" };

            Map<String, String> keyValueMap = getKeyValuePairFromFilter(filter, QUERY_FILTER_KEYS);

            for (String key : keyValueMap.keySet()) {
                 String value = keyValueMap.get(key);
                 //Process values here

                case "name":
                ...
                break;
                case "type":
                ...
                break;
            }
    }

public Map<String, String> getKeyValuePairFromFilter(final String filter, final String[] validFilterKeys) {

         final String QUERY_FILTER_PATTERN = "^(?:\\s*((?:[^\\:\\:\\|\\s]+\\s+)*[^\\:\\:\\|\\s]+)\\s*\\:\\:\\s*((?:[^\\:\\:\\|\\s]+\\s+)*[^\\:\\:\\|\\s]+)\\s*(?:\\|(?!\\s*$)|$))+$";

        final String QUERY_PARAM_PAIR_DELIMITER = "\\|";
        final String QUERY_PARAM_VALUE_DELIMITER = "::";

        Map<String, String> map = new LinkedHashMap<>();

        if (!StringUtils.isEmpty(filter)) {

            if (!filter.matches(QUERY_FILTER_PATTERN)) {

                throw BadRequestException.parameterInvalidExpectedValue("filter",
                        "key1::value1|key2::value2|key3::value3...");
            }

            String[] queryParamArray = filter.split(QUERY_PARAM_PAIR_DELIMITER);

            if (!StringUtils.isEmpty(queryParamArray)) {

                List<String> validQueryParamList = Arrays.asList(validFilterKeys);

                for (int i = 0; i < queryParamArray.length; i++) {

                    String queryParamPair = queryParamArray[i];

                    if (!StringUtils.isEmpty(queryParamPair)) {
                        String[] queryParamPairArray = queryParamPair.split(QUERY_PARAM_VALUE_DELIMITER);

                        if (!StringUtils.isEmpty(queryParamPairArray) && queryParamPairArray.length == 2) {
                            String key = queryParamPairArray[0].trim();
                            if (validQueryParamList.contains(key)) {
                                String valueText = queryParamPairArray[1].trim();
                                logger.debug("Adding key:value pair in the map: [{} : {}]", key, valueText);
                                map.put(key, valueText);
                            }
                        }
                    }
                }
            }
        }

        return map;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...