Vodič za pretvorbe proljetnih tipova

1. Uvod

U ovom ćemo članku pogledati pretvorbe tipova Springa.

Spring nudi gotove razne pretvarače za ugrađene tipove; to znači pretvaranje u / iz osnovnih tipova poput String, Integer, Boolean i niz drugih vrsta.

Osim toga, Spring također nudi solidni SPI za pretvorbu tipa za razvoj naših prilagođenih pretvarača.

2. Ugrađeni Konverters

Počet ćemo s pretvaračima koji su dostupni odmah na proljeće; pogledajmo Niz do Cijeli broj pretvorba:

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

Jedino što ovdje moramo učiniti je automatsko povezivanje ConversionService koje pruža Spring i nazovite Pretvoriti() metoda. Prvi argument je vrijednost koju želimo pretvoriti, a drugi argument je ciljna vrsta u koju želimo pretvoriti.

Osim ovoga Niz do Cijeli broj na primjer, dostupno nam je puno raznih drugih kombinacija.

3. Izrada prilagođenog Konverter

Pogledajmo primjer pretvaranja a Niz prikaz an Zaposlenik do an Zaposlenik primjer.

Evo Zaposlenik razred:

zaposlenik u javnoj klasi {private long id; privatna dvostruka plaća; // standardni konstruktori, getteri, postavljači}

The Niz bit će par odvojen zarezom koji predstavlja iskaznica i plaća. Na primjer, "1.50000,00".

Da bismo stvorili naš običaj Konverter, moramo implementirati Konverter sučelje i implementirati Pretvoriti() metoda:

javna klasa StringToEfficieeConverter implementira Converter {@Override javni pretvorbu zaposlenika (String from) {String [] data = from.split (","); vratiti novog zaposlenika (Long.parseLong (podaci [0]), Double.parseDouble (podaci [1])); }}

Još nismo gotovi. Također moramo reći Springu o ovom novom pretvaraču dodavanjem StringToEfficieeConverter prema FormatterRegistry. To se može učiniti primjenom WebMvcConfigurer i nadjačavanje addFormatters () metoda:

@Configuration javna klasa WebConfig implementira WebMvcConfigurer {@Override public void addFormatters (Registar FormatterRegistry) {registry.addConverter (novi StringToEfficieeConverter ()); }}

I to je to. Naš novi Konverter je sada dostupan ConversionService i možemo ga koristiti na isti način kao i bilo koji drugi ugrađeni Konverter:

@Test public void whenConvertStringToEfficiee_thenSuccess () {Zaposlenik zaposlenik = conversionService .convert ("1.50000,00", Employee.class); Zaposlenik stvarniZaposlenik = novi zaposlenik (1, 50000.00); assertThat (conversionService.convert ("1.50000,00", Employee.class)) .isEqualToComparingFieldByField (stvarni zaposlenik); }

3.1. Implicitna konverzija

Osim ove eksplicitne pretvorbe pomoću ConversionService, Spring je također sposoban implicitno pretvoriti vrijednosti upravo u Kontroler metode za sve registrirane pretvarače:

@RestController javna klasa StringToEfficieeConverterController {@GetMapping ("/ string-to-worker") javni ResponseEntity getStringToEfficiee (@RequestParam ("zaposlenik") zaposlenik zaposlenika) {return ResponseEntity.ok (zaposlenik); }}

Ovo je prirodniji način korištenja Konverters. Dodajmo test kako bismo ga vidjeli na djelu:

@Test public void getStringToEfficieeTest () baca iznimku {mockMvc.perform (get ("/ string-to-worker? Worker = 1,2000")). AndDo (print ()) .andExpect (jsonPath ("$. Id", je (1))) .andExpect (jsonPath ("$. plaća", je (2000.0)))}

Kao što vidite, test će ispisati sve detalje zahtjeva kao i odgovor. Ovdje je Zaposlenik objekt u JSON formatu koji se vraća kao dio odgovora:

{"id": 1, "plaća": 2000,0}

4. Stvaranje a ConverterFactory

Također je moguće stvoriti ConverterFactory koja stvara Konverters na zahtjev. To je posebno korisno u stvaranju Konverters za Enum.

Pogledajmo stvarno jednostavan Enum:

načini javnog popisa {ALPHA, BETA; }

Dalje, izradimo a StringToEnumConverterFactory koje mogu generirati Konverters za pretvorbu a Niz bilo kojem Enum:

@Component javna klasa StringToEnumConverterFactory implementira ConverterFactory {privatna statička klasa StringToEnumConverter implementira Converter {private Class enumType; javni StringToEnumConverter (klasa enumType) {this.enumType = enumType; } javna T pretvorba (izvor niza) {return (T) Enum.valueOf (this.enumType, source.trim ()); }} @Override javni pretvarač getConverter (Class targetType) {return new StringToEnumConverter (targetType); }}

Kao što vidimo, tvornička klasa interno koristi implementaciju Konverter sučelje.

Ovdje treba napomenuti da iako ćemo koristiti svoj Načini nabrajanja da bismo demonstrirali upotrebu, nismo spomenuli Enum bilo gdje u StringToEnumConverterFactory. Naša tvornička klasa dovoljno je generička da generira Konverterna zahtjev za bilo koji Enum tip.

Sljedeći je korak registriranje ove tvorničke klase onako kako smo registrirali našu Konverter u prethodnom primjeru:

@Override public void addFormatters (registar FormatterRegistry) {registry.addConverter (novi StringToEfficieeConverter ()); registry.addConverterFactory (novi StringToEnumConverterFactory ()); }

Sada ConversionService je spreman za pretvorbu Nizs do Enums:

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

5. Stvaranje a Generički pretvarač

A Generički pretvarač pruža nam veću fleksibilnost za stvaranje a Konverter za općenitiju upotrebu po cijenu gubitka neke vrste sigurnosti.

Razmotrimo primjer pretvaranja Cijeli broj, Dvostruko, ili a Niz do a BigDecimal vrijednost.Ne trebamo napisati tri Konverters za ovo. Jednostavan Generički pretvarač mogao poslužiti svrsi.

Prvi je korak reći Springu koje su vrste konverzija podržane. To radimo stvaranjem a Postavi od ConvertiblePair:

javna klasa GenericBigDecimalConverter implementira GenericConverter {@Override public Set getConvertibleTypes () {ConvertiblePair [] parovi = new ConvertiblePair [] {new ConvertiblePair (Number.class, BigDecimal.class), new ConvertiblePair (Stringeclass.Class. return ImmutableSet.copyOf (parovi); }}

Sljedeći je korak poništiti Pretvoriti() metoda u istoj klasi:

@Override public Object convert (Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {if (sourceType.getType () == BigDecimal.class) {return source; } if (sourceType.getType () == String.class) {Niz niza = (Niz) izvor; vrati novi BigDecimal (broj); } else {Broj broj = (Broj) izvor; Pretvoreno BigDecimal = novo BigDecimal (number.doubleValue ()); povratak convert.setScale (2, BigDecimal.ROUND_HALF_EVEN); }}

The Pretvoriti() metoda je što jednostavnija. Međutim TypeDescriptor pruža nam veliku fleksibilnost u pogledu dobivanja detalja u vezi s izvorom i ciljnom vrstom.

Kao što ste već mogli pretpostaviti, sljedeći je korak to registrirati Konverter:

@Override public void addFormatters (registar FormatterRegistry) {registry.addConverter (novi StringToEfficieeConverter ()); registry.addConverterFactory (novi StringToEnumConverterFactory ()); registry.addConverter (novi GenericBigDecimalConverter ()); }

Koristeći ovo Konverter je sličan ostalim primjerima koje smo već vidjeli:

@Test public void whenConvertingToBigDecimalUsingGenericConverter_thenSuccess () {assertThat (conversionService .convert (Integer.valueOf (11), BigDecimal.class)) .isEqualTo (BigDecimal.valueOf (11.00) .set.ROD. 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. Zaključak

U ovom uputstvu vidjeli smo kako koristiti i proširiti Springov sustav pretvorbe tipa s raznim primjerima.

Kao i uvijek, puni izvorni kod za ovaj članak nalazi se na GitHubu.