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.