1. Введение
Проще говоря, Spring интенсивно использует редакторы свойств для управления преобразованием между строковыми
значениями и пользовательскими типами объектов ;
это основано на Java Beans PropertyEditor .
В этом руководстве мы рассмотрим два различных варианта использования для демонстрации автоматической привязки редактора свойств и привязки пользовательского редактора свойств .
2. Автоматическая привязка редактора свойств
Стандартная инфраструктура JavaBeans
автоматически обнаружит классы PropertyEditor
, если они находятся в том же пакете, что и класс, с которым они работают. Кроме того, они должны иметь то же имя, что и этот класс, плюс суффикс Editor .
Например, если мы создаем класс модели CreditCard
, мы должны назвать класс редактора CreditCardEditor.
Давайте теперь рассмотрим практический пример привязки свойств.
В нашем сценарии мы передадим номер кредитной карты в качестве переменной пути в URL-адресе запроса и привяжем это значение как объект CreditCard
.
Давайте сначала создадим класс модели CreditCard
, определяющий поля rawCardNumber,
идентификационный номер банка (первые 6 цифр), номер счета (цифры от 7 до 15) и контрольный код (последняя цифра):
public class CreditCard {
private String rawCardNumber;
private Integer bankIdNo;
private Integer accountNo;
private Integer checkCode;
// standard constructor, getters, setters
}
Далее мы создадим класс CreditCardEditor
. Это реализует бизнес-логику для преобразования номера кредитной карты, заданного в виде строки
, в объект CreditCard
.
Класс редактора свойств должен расширять PropertyEditorSupport
и реализовывать методы getAsText()
и setAsText()
:
public class CreditCardEditor extends PropertyEditorSupport {
@Override
public String getAsText() {
CreditCard creditCard = (CreditCard) getValue();
return creditCard == null ? "" : creditCard.getRawCardNumber();
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (StringUtils.isEmpty(text)) {
setValue(null);
} else {
CreditCard creditCard = new CreditCard();
creditCard.setRawCardNumber(text);
String cardNo = text.replaceAll("-", "");
if (cardNo.length() != 16)
throw new IllegalArgumentException(
"Credit card format should be xxxx-xxxx-xxxx-xxxx");
try {
creditCard.setBankIdNo( Integer.valueOf(cardNo.substring(0, 6)) );
creditCard.setAccountNo( Integer.valueOf(
cardNo.substring(6, cardNo.length() - 1)) );
creditCard.setCheckCode( Integer.valueOf(
cardNo.substring(cardNo.length() - 1)) );
} catch (NumberFormatException nfe) {
throw new IllegalArgumentException(nfe);
}
setValue(creditCard);
}
}
}
Метод getAsText()
вызывается при сериализации объекта в строку,
а setAsText()
используется для преобразования строки
в другой объект.
Так как эти классы находятся в одном пакете, нам больше ничего не нужно делать для привязки Editor
к типу CreditCard
.
Теперь мы можем представить это как ресурс в REST API; операция принимает номер кредитной карты в качестве переменной пути запроса, и Spring свяжет это текстовое значение как объект CrediCard
и передаст его в качестве аргумента метода:
@GetMapping(value = "/credit-card/{card-no}",
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public CreditCard parseCreditCardNumber(
@PathVariable("card-no") CreditCard creditCard) {
return creditCard;
}
Например, для примера URL-адреса запроса /property-editor/credit-card/1234-1234-1111-0019
мы получим ответ:
{
"rawCardNumber": "1234-1234-1111-0011",
"bankIdNo": 123412,
"accountNo": 341111001,
"checkCode": 9
}
3. Привязка редактора пользовательских свойств
Если у нас нет требуемого класса типа и класса редактора свойств в одном пакете или с ожидаемыми соглашениями об именах, нам придется определить пользовательскую привязку между требуемым типом и редактором свойств.
В нашем сценарии привязки пользовательского редактора свойств значение String
будет передано в URL-адресе как переменная пути, и мы привяжем это значение как объект ExoticType
, который просто сохранит значение как атрибут.
Как и в разделе 2, давайте сначала создадим класс модели ExoticType:
public class ExoticType {
private String name;
// standard constructor, getters, setters
}
И наш класс пользовательского редактора свойств CustomExoticTypeEditor
, который снова расширяет PropertyEditorSupport
:
** **
public class CustomExoticTypeEditor extends PropertyEditorSupport {
@Override
public String getAsText() {
ExoticType exoticType = (ExoticType) getValue();
return exoticType == null ? "" : exoticType.getName();
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
ExoticType exoticType = new ExoticType();
exoticType.setName(text.toUpperCase());
setValue(exoticType);
}
}
Поскольку Spring не может обнаружить редактор свойств, нам понадобится метод с аннотацией @InitBinder
в нашем классе Controller
, который регистрирует редактор:
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(ExoticType.class,
new CustomExoticTypeEditor());
}
Затем мы можем привязать пользовательский ввод к объекту ExoticType
:
@GetMapping(
value = "/exotic-type/{value}",
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public ExoticType parseExoticType(
@PathVariable("value") ExoticType exoticType) {
return exoticType;
}
Для примера URL-адреса запроса /property-editor/exotic-type/passion-fruit
мы получим образец ответа:
{
"name": "PASSION-FRUIT"
}
4. Вывод
В этой быстрой статье мы увидели, как можно использовать автоматическую и пользовательскую привязку редактора свойств для преобразования удобочитаемых строковых
значений в сложные типы Java.
Полный исходный код наших примеров здесь, как всегда, находится на GitHub .