Настроить параметры запроса отображения и поля внутри DTO?

У меня есть следующий класс:

public class MyDTO { 

       private String kiosk;
       ...
}

и следующий URL:

http://localhost:1234/mvc/controllerUrl?kiosk=false

и следующий метод контроллера:

@RequestMapping(method = RequestMethod.GET, produces = APPLICATION_JSON)
@ResponseBody
public ResponseEntity<List<?>> getRequestSupportKludge(final MyDTO myDTO, BindingResult bindingResult) {
    ...
}

Теперь он работает хорошо, а логическое поле разрешается правильно.

Теперь параметр url изменился следующим образом:

http://localhost:1234/mvc/controllerUrl?new_kiosk=false

Я не хочу менять имя параметра внутри DTO. Есть ли способ сказать весну, чтобы понять, что new_kiosk значение параметра запроса должно быть введено в kiosk поле?

3 ответа

Решение

Помимо установки дополнительного установщика, вы можете изменить регистр, сделав собственный преобразователь аргументов. Есть несколько способов сделать это, но уже есть хорошо обсужденный пост. На вашем месте я бы сосредоточился на ответе шутника. Следуйте за ним шаг за шагом, и все, что вам нужно сделать, это аннотировать ваш DTO чем-то вроде:

public class MyDTO { 

       @ParamName("new_kiosk")
       private String kiosk;
       ...
}

Обратите внимание, что даже если вы не можете изменить MyDTO класс, вы все равно можете следовать пользовательскому маршруту решателя. В этом посте я ответил, как вы можете написать аннотацию типа параметра. Комбинируя два поста, вы можете легко придумать аннотацию, например: @ParamMapper это определило бы отображение от запроса до свойств. Придумай что-то вроде

 getRequestSupportKludge(@ParamMapper("new_kiosk;kiosk") MyDTO myDTO, BindingResult bindingResult)

Есть разные способы сделать это.

Если вы можете изменить MyDTO В классе проще всего добавить сеттер, как это было предложено М.Дейном:

public class MyDTO { 

       private String kiosk;
       ...
       public void setNew_kiosk(String kiosk) {
           this.kiosk = kiosk;
       }
}

Таким образом, вы можете обрабатывать http://localhost:1234/mvc/controllerUrl?kiosk=false так же как http://localhost:1234/mvc/controllerUrl?new_kiosk=false

Если вам не разрешено это делать (поскольку DTO является частью библиотеки, которую вы не можете изменять или...), вы можете использовать фильтр, сопоставленный с /mvc/controllerUrl, что бы завернуть запрос с кастомом HttpServlerRequestWrapper это переопределит следующие методы:

String  getParameter(String name)
Map<String,String[]>    getParameterMap()
Enumeration<String>     getParameterNames()
String[]    getParameterValues(String name)

вызов базовых методов запроса и обработка имени специального параметра. Пример:

String[]    getParameterValues(String name) {
    String[] values = req.getParameterValues(name); // req is the wrapped request
    if ("kiosk".equals(name) && (values == null) {  // will accept both names
        values = req.getParameterValues("new_kiosk"); // try alternate name
    }
    return values;
}

Это будет намного сложнее для написания и тестирования, поэтому идите по этому пути, только если вы не можете изменить MyDTO учебный класс.

Вы также можете попробовать использовать пользовательскую реализацию WebBindingInitializer, Из справочного руководства Spring Framework:

Чтобы выполнить инициализацию привязки данных, вы можете предоставить пользовательскую реализацию WebBindingInitializer интерфейс, который вы затем включаете, предоставляя настраиваемую конфигурацию бина для AnnotationMethodHandlerAdapter , таким образом, переопределяя конфигурацию по умолчанию.

Осторожно: рекомендуется использовать это для регистрации пользовательских редакторов для всего приложения, а не для вашего варианта использования. И Spring Framework часто описывается как легко расширяемый, но не переопределяемый. Пусть покупатель будет бдителен...

Резюме: попробуйте использовать метод 1, если вы не можете, затем используйте метод 2, и попробуйте метод 3, только если у вас есть другие причины для использования пользовательского WebBindingInitializer

Вы можете использовать@JsonPropertyна поле DTO для сопоставления его с запросом JSON, если имя поля в запросе отличается от поля, определенного в DTO.

Другие вопросы по тегам