Настроить параметры запроса отображения и поля внутри 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.