Spring Custom Property Editor

1. Inleiding

Simpel gezegd, Spring gebruikt veel vastgoededitors voor het beheren van de conversie tussen Draad waarden en gebruik Voorwerp types; dit is gebaseerd op Java Beans PropertyEditor.

In deze zelfstudie bespreken we twee verschillende gebruiksscenario's om te demonstreren automatische binding van eigenschappeneditor en binding van aangepaste eigenschappeneditor.

2. Automatische binding van eigenschappeneditor

Standaard JavaBeans infrastructuur zal automatisch ontdekken PropertyEditor klassen als ze zich in hetzelfde pakket bevinden als de klasse die ze behandelen. Deze moeten ook dezelfde naam hebben als die klasse plus de Editor achtervoegsel.

Als we bijvoorbeeld een Kredietkaart model class, dan moeten we de editor class een naam geven Creditcard-editor.

Laten we nu doorgaan een praktisch voorbeeld van eigendomsbinding.

In ons scenario geven we een creditcardnummer door als padvariabele in de verzoek-URL en binden we die waarde als een credit card voorwerp.

Laten we eerst het Kredietkaart modelklasse die velden definieert rawCardNumber, Bankidentificatienummer (de eerste 6 cijfers), rekeningnummer (cijfers van 7 tot 15) en controlecode (laatste cijfer):

openbare klasse CreditCard {private String rawCardNumber; private Integer bankIdNo; privé Integer-accountNee; privé geheel getal checkCode; // standard constructor, getters, setters}

Vervolgens maken we het Creditcard-editor klasse. Dit implementeert de bedrijfslogica voor het converteren van het creditcardnummer dat wordt gegeven als een Draad naar een Kredietkaart voorwerp.

De property editor-klasse moet worden uitgebreid PropertyEditorSupport en implementeer het getAsText () en setAsText () methoden:

openbare klasse CreditCardEditor breidt PropertyEditorSupport uit {@Override public String getAsText () {CreditCard creditCard = (CreditCard) getValue (); retourneer creditcard == null? "": creditCard.getRawCardNumber (); } @Override public void setAsText (String-tekst) gooit IllegalArgumentException {if (StringUtils.isEmpty (tekst)) {setValue (null); } anders {CreditCard creditCard = nieuwe CreditCard (); creditCard.setRawCardNumber (tekst); String cardNo = text.replaceAll ("-", ""); if (cardNo.length ()! = 16) throw new IllegalArgumentException ("Creditcardformaat moet xxxx-xxxx-xxxx-xxxx zijn"); probeer {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) {gooi nieuwe IllegalArgumentException (nfe); } setValue (creditcard); }}}

De getAsText () methode wordt aangeroepen bij het serialiseren van een object naar een Draad, terwijl setAsText () wordt gebruikt om een Draad naar een ander object.

Aangezien deze klassen zich in hetzelfde pakket bevinden, hoeven we niets anders te doen om het Editor voor type Kredietkaart.

We kunnen dit nu weergeven als een bron in een REST API; de bewerking neemt een creditcardnummer als een verzoekpadvariabele en Spring zal die tekstwaarde binden als een CrediCard object en geef het door als een methode-argument:

@GetMapping (value = "/ creditcard / {card-no}", produceert = MediaType.APPLICATION_JSON_UTF8_VALUE) openbare CreditCard parseCreditCardNumber (@PathVariable ("card-no") CreditCard creditcard) {retourneer creditcard; }

Bijvoorbeeld voor een voorbeeldverzoek-URL / property-editor / creditcard / 1234-1234-1111-0019, we krijgen het antwoord:

{"rawCardNumber": "1234-1234-1111-0011", "bankIdNo": 123412, "accountNo": 341111001, "checkCode": 9}

3. Binding van de Editor voor aangepaste eigenschappen

Als we de vereiste type-klasse en de eigenschap-editor-klasse niet in hetzelfde pakket of met de verwachte naamgevingsconventies hebben, moeten we een aangepaste binding definiëren tussen het vereiste type en de eigenschappen-editor.

In ons bindende scenario voor de editor voor aangepaste eigenschappen, a Draad waarde wordt in de URL doorgegeven als padvariabele, en we binden die waarde als een ExoticType object dat alleen de waarde als een attribuut behoudt.

Laten we, net als in sectie 2, eerst een modelklasse maken Exotisch Type:

openbare klasse ExoticType {privé Stringnaam; // standard constructor, getters, setters}

En onze klasse voor aangepaste eigenschappen-editor CustomExoticTypeEditor die zich opnieuw uitstrekt PropertyEditorSupport:

openbare klasse CustomExoticTypeEditor breidt PropertyEditorSupport uit {@Override openbare tekenreeks getAsText () {ExoticType exoticType = (ExoticType) getValue (); return exoticType == null? "": exoticType.getName (); } @Override public void setAsText (String-tekst) gooit IllegalArgumentException {ExoticType exoticType = nieuw ExoticType (); exotischeType.setName (text.toUpperCase ()); setValue (exoticType); }}

Omdat Spring de eigenschappeneditor niet kan detecteren, we hebben een methode nodig die is geannoteerd met @InitBinder in onze Controller klasse die de editor registreert:

@InitBinder openbare void initBinder (WebDataBinder-binder) {binder.registerCustomEditor (ExoticType.class, nieuwe CustomExoticTypeEditor ()); }

Dan kunnen we de gebruikersinvoer binden aan ExoticType voorwerp:

@GetMapping (waarde = "/ exotisch-type / {waarde}", produceert = MediaType.APPLICATION_JSON_UTF8_VALUE) openbaar ExoticType parseExoticType (@PathVariable ("waarde") ExoticType exoticType) {return exoticType; }

Voor de URL van het voorbeeldverzoek / property-editor / exotisch-type / passievrucht, we krijgen het voorbeeldantwoord:

{"name": "PASSION-FRUIT"}

4. Conclusie

In dit korte artikel hebben we gezien hoe we automatische en aangepaste eigenschap-editor-binding kunnen gebruiken om voor mensen leesbaar te converteren Draad waarden voor complexe Java-typen.

De volledige broncode van onze voorbeelden hier is, zoals altijd, op GitHub.