Sprievodca konverziou typu pružiny

1. Úvod

V tomto článku sa pozrieme na jarné konverzie typu.

Pružina poskytuje rôzne typy prevodníkov pre zabudované typy; to znamená prevod na / zo základných typov ako Reťazec, Celé číslo, Boolovská hodnota a množstvo ďalších typov.

Okrem toho poskytuje Spring tiež solídny typ konverzie SPI pre vývoj našich vlastných prevodníkov.

2. Zabudované Prevádzačs

Začneme s prevodníkmi, ktoré sú k dispozícii už na jar na jar; poďme sa pozrieť na String do Celé číslo konverzia:

@Autowired ConversionService conversionService; @Test public void whenConvertStringToIntegerUsingDefaultConverter_thenSuccess () {assertThat (conversionService.convert ("25", Integer.class)). IsEqualTo (25); }

Jediné, čo tu musíme urobiť, je autowire ConversionService poskytuje Jar a zavolajte na konvertovať () metóda. Prvý argument je hodnota, ktorú chceme previesť, a druhý argument je cieľový typ, na ktorý chceme prevádzať.

Okrem toho String do Celé číslo napríklad máme k dispozícii veľa rôznych ďalších kombinácií.

3. Vytvorenie vlastného Prevádzač

Pozrime sa na príklad premeny a String zastúpenie Zamestnanec do an Zamestnanec inštancia.

Tu je Zamestnanec trieda:

public class Employee {private long id; dvojitý súkromný plat; // štandardné konštruktory, getre, setre}

The String bude dvojica oddelená čiarkou id a plat. Napríklad „1 500 000,00“.

Aby sme vytvorili náš zvyk Prevádzač, musíme implementovať Prevádzač rozhranie a implementovať konvertovať () metóda:

public class StringToEmployeeConverter implementuje Converter {@Override public Employee convert (String from) {String [] data = from.split (","); vrátiť nového zamestnanca (Long.parseLong (data [0]), Double.parseDouble (data [1])); }}

Ešte sme neskončili. Spring je tiež potrebné povedať o tomto novom prevádzači pridaním StringToEmployeeConverter do FormatterRegistry. To sa dá dosiahnuť implementáciou WebMvcConfigurer a prvoradé addFormatters () metóda:

@Configuration public class WebConfig implementuje WebMvcConfigurer {@Override public void addFormatters (register FormatterRegistry) {registry.addConverter (nový StringToEmployeeConverter ()); }}

A to je všetko. Náš nový Prevádzač je teraz k dispozícii pre ConversionService a môžeme ho používať rovnako ako akýkoľvek iný vstavaný modul Prevádzač:

@Test public void whenConvertStringToEmployee_thenSuccess () {Employee employee = conversionService .convert ("1 50000,00", Employee.class); Skutočný zamestnanecZamestnanec = nový zamestnanec (1 500 000,00); assertThat (conversionService.convert ("1 500 000,00", Employee.class)) .isEqualToComparingFieldByField (actualEmployee); }

3.1. Implicitná konverzia

Okrem týchto výslovných prevodov pomocou ConversionService, Jar je tiež schopná implicitne prevádzať hodnoty priamo do Kontrolór metódy pre všetkých registrovaných prevádzačov:

@RestController verejná trieda StringToEmployeeConverterController {@GetMapping ("/ string-to-employee") public ResponseEntity getStringToEmployee (@RequestParam ("zamestnanec") zamestnanec zamestnanec) {return ResponseEntity.ok (zamestnanec); }}

Toto je prirodzenejší spôsob použitia Prevádzačs. Pridajte test, aby sme ho videli v akcii:

@ Test public void getStringToEmployeeTest () vyvolá výnimku {mockMvc.perform (get ("/ string-to-employee? Employee = 1,2000")) .andDo (print ()) .andExpect (jsonPath ("$. Id", is (1))) .andExpect (jsonPath ("$. plat", is (2000.0)))}

Ako vidíte, test vytlačí všetky podrobnosti žiadosti, ako aj odpovede. Tu je Zamestnanec objekt vo formáte JSON, ktorý sa vráti ako súčasť odpovede:

{"id": 1, "plat": 2000,0}

4. Vytvorenie a ConverterFactory

Je tiež možné vytvoriť ConverterFactory ktorý vytvára Prevádzačs na požiadanie. To je obzvlášť užitočné pri vytváraní Prevádzačs pre Enums.

Pozrime sa na skutočne jednoduchý Enum:

režimy verejného výčtu {ALPHA, BETA; }

Ďalej vytvoríme a StringToEnumConverterFactory ktoré môžu generovať Prevádzačs na premenu a String k hocijakej Enum:

@Component public class StringToEnumConverterFactory implementuje ConverterFactory {súkromná statická trieda StringToEnumConverter implementuje Converter {private Class enumType; public StringToEnumConverter (trieda enumType) {this.enumType = enumType; } public T convert (String source) {return (T) Enum.valueOf (this.enumType, source.trim ()); }} @Override public Converter getConverter (Class targetType) {return new StringToEnumConverter (targetType); }}

Ako vidíme, továrenská trieda interne používa implementáciu Prevádzač rozhranie.

Tu si treba uvedomiť jednu vec, že ​​aj keď použijeme našu Režimy Enum na demonštráciu použitia sme nespomenuli Enum kdekoľvek v StringToEnumConverterFactory. Naša továrenská trieda je dostatočne generická na generovanie Prevádzačs na požiadanie akékoľvek Enum typu.

Ďalším krokom je registrácia tejto továrenskej triedy, keď sme registrovali našu Prevádzač v predchádzajúcom príklade:

@Override public void addFormatters (register FormatterRegistry) {registry.addConverter (nový StringToEmployeeConverter ()); registry.addConverterFactory (nový StringToEnumConverterFactory ()); }

Teraz ConversionService je pripravený na konverziu Strings až Enums:

@Test public void whenConvertStringToEnum_thenSuccess () {assertThat (conversionService.convert ("ALPHA", Modes.class)) .isEqualTo (Modes.ALPHA); }

5. Vytvorenie a GenericConverter

A GenericConverter poskytuje nám väčšiu flexibilitu pri vytváraní Prevádzač na všeobecnejšie použitie za cenu straty bezpečnosti niektorých typov.

Zvážme príklad premeny Celé číslo, Dvojitý, alebo a String do a BigDecimal hodnota. Nemusíme písať tri Prevádzačs pre toto. Jednoduchý GenericConverter mohlo slúžiť účelu.

Prvým krokom je povedať spoločnosti Spring, aké typy konverzií sú podporované. Robíme to tak, že vytvoríme a Nastaviť z ConvertiblePair:

verejná trieda GenericBigDecimalConverter implementuje GenericConverter {@Override public Set getConvertibleTypes () {ConvertiblePair [] pary = nový ConvertiblePair [] {nový ConvertiblePair (Number.class, BigDecimal.class), nový ConvertiblePair (String.class, BigDecim) return ImmutableSet.copyOf (páry); }}

Ďalším krokom je prepísanie konvertovať () metóda v rovnakej triede:

@Override public Object convert (Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {if (sourceType.getType () == BigDecimal.class) {návratový zdroj; } if (sourceType.getType () == String.class) {Číslo reťazca = (Reťazec) zdroj; vrátiť nový BigDecimal (číslo); } else {Number number = (Number) source; BigDecimal prevedený = nový BigDecimal (number.doubleValue ()); návrat prevedený.setRozsah (2, BigDecimal.ROUND_HALF_EVEN); }}

The konvertovať () metóda je tak jednoduchá, ako len môže byť. Avšak Deskriptor typu poskytuje nám veľkú flexibilitu, pokiaľ ide o získanie podrobností týkajúcich sa zdroja a cieľového typu.

Ako ste už mohli uhádnuť, ďalším krokom je registrácia Prevádzač:

@Override public void addFormatters (register FormatterRegistry) {registry.addConverter (nový StringToEmployeeConverter ()); registry.addConverterFactory (nový StringToEnumConverterFactory ()); registry.addConverter (nový GenericBigDecimalConverter ()); }

Pomocou tohto Prevádzač je podobný ostatným príkladom, ktoré sme už videli:

@Test public void whenConvertingToBigDecimalUsingGenericConverter_thenSuccess () {assertThat (conversionService .convert (Integer.valueOf (11), BigDecimal.class)) .isEqualTo (BigDecimal.valueOf (11,00) .setScale (11,00) .setScale (11,00) .setScale (11,00) .setScale assertThat (conversionService .convert (Double.valueOf (25.23), BigDecimal.class)) .isEqualByComparingTo (BigDecimal.valueOf (Double.valueOf (25.23))); assertThat (conversionService.convert ("2.32", BigDecimal.class)) .isEqualTo (BigDecimal.valueOf (2.32)); }

6. Záver

V tomto tutoriáli sme videli, ako používať a rozšíriť jarný systém prepočtu typov o rôzne príklady.

Celý zdrojový kód tohto článku nájdete ako vždy na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found