Gids voor conversies van het type veer

1. Inleiding

In dit artikel zullen we de typeconversies van Spring bekijken.

Spring biedt kant-en-klare verschillende converters voor ingebouwde typen; dit betekent het converteren van / naar basistypen zoals Tekenreeks, geheel getal, booleaans en een aantal andere typen.

Afgezien hiervan biedt Spring ook een solide SPI voor typeconversie voor het ontwikkelen van onze aangepaste converters.

2. Ingebouwd Converters

We beginnen met de converters die in het voorjaar out-of-the-box beschikbaar zijn; laten we eens kijken naar de Draad naar Geheel getal conversie:

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

Het enige dat we hier hoeven te doen, is het ConversionService geleverd door Spring en bel de converteren() methode. Het eerste argument is de waarde die we willen converteren en het tweede argument is het doeltype waarnaar we willen converteren.

Behalve dit Draad naar Geheel getal er zijn bijvoorbeeld veel verschillende andere combinaties voor ons beschikbaar.

3. Een aangepast Converter

Laten we eens kijken naar een voorbeeld van het converteren van een Draad vertegenwoordiging van een Werknemer aan een Werknemer voorbeeld.

Hier is de Werknemer klasse:

openbare klasse Medewerker {privé lange id; particulier dubbel salaris; // standaard constructeurs, getters, setters}

De Draad zal een door komma's gescheiden paar zijn dat vertegenwoordigt ID kaart en salaris. Bijvoorbeeld "1.50000,00".

Om onze custom Converter, we moeten het Converter interface en implementeer het converteren() methode:

openbare klasse StringToEmployeeConverter implementeert Converter {@Override public Employee convert (String from) {String [] data = from.split (","); retourneer nieuwe werknemer (Long.parseLong (data [0]), Double.parseDouble (data [1])); }}

We zijn nog niet klaar. We moeten Spring ook over deze nieuwe converter informeren door de extensie StringToEmployeeConverter naar de FormatterRegistry. Dit kan worden gedaan door de implementatie van het WebMvcConfigurer en doorslaggevend addFormatters () methode:

@Configuration openbare klasse WebConfig implementeert WebMvcConfigurer {@Override openbare ongeldige addFormatters (FormatterRegistry-register) {registry.addConverter (nieuwe StringToEmployeeConverter ()); }}

En dat is het. Onze nieuwe Converter is nu beschikbaar voor de ConversionService en we kunnen het op dezelfde manier gebruiken als elk ander ingebouwd apparaat Converter:

@Test openbaar ongeldig whenConvertStringToEmployee_thenSuccess () {Werknemer werknemer = conversionService .convert ("1.50000.00", Werknemer.klasse); Werkelijke werknemer = nieuwe werknemer (1.500.000,00); assertThat (conversionService.convert ("1.50000.00", Employee.class)) .isEqualToComparingFieldByField (actualEmployee); }

3.1. Impliciete conversie

Naast deze expliciete conversie met behulp van de ConversionService, De lente is ook in staat om impliciet waarden direct in Controller methoden voor alle geregistreerde converters:

@RestController openbare klasse StringToEmployeeConverterController {@GetMapping ("/ string-to-employee") openbare ResponseEntity getStringToEmployee (@RequestParam ("werknemer") Werknemer werknemer) {return ResponseEntity.ok (werknemer); }}

Dit is een meer natuurlijke manier om de Converters. Laten we een test toevoegen om het in actie te zien:

@Test public void getStringToEmployeeTest () genereert Uitzondering {mockMvc.perform (get ("/ string-to-employee? Employee = 1,2000")) .andDo (print ()) .andExpect (jsonPath ("$. Id", is (1))) .andExpect (jsonPath ("$. salaris", is (2000.0)))}

Zoals u kunt zien, zal de test alle details van het verzoek en het antwoord afdrukken. Hier is de Werknemer object in JSON-indeling dat wordt geretourneerd als onderdeel van het antwoord:

{"id": 1, "salaris": 2000.0}

4. Een ConverterFactory

Het is ook mogelijk om een ConverterFactory dat creëert Converters op aanvraag. Dit is vooral handig bij het maken van Converters voor Enums.

Laten we eens kijken naar een heel eenvoudige Enum:

openbare opsomming Modi {ALPHA, BETA; }

Laten we vervolgens een StringToEnumConverterFactory dat kan genereren Converters voor het converteren van een Draad aan elk Enum:

@Component openbare klasse StringToEnumConverterFactory implementeert ConverterFactory {privé statische klasse StringToEnumConverter implementeert Converter {privéklasse enumType; openbare StringToEnumConverter (Klasse enumType) {this.enumType = enumType; } openbare T convert (String source) {return (T) Enum.valueOf (this.enumType, source.trim ()); }} @Override public Converter getConverter (Class targetType) {retourneer nieuwe StringToEnumConverter (targetType); }}

Zoals we kunnen zien, gebruikt de fabrieksklasse intern een implementatie van Converter koppel.

Een ding om op te merken is dat hoewel we onze Modi Enum om het gebruik te demonstreren, hebben we de Enum overal in de StringToEnumConverterFactory. Onze fabrieksklasse is generiek genoeg om het Converters op aanvraag voor elk Enum type.

De volgende stap is om deze fabrieksklasse te registreren zoals we onze Converter in het vorige voorbeeld:

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

Nu de ConversionService is klaar om te converteren Draads naar Enums:

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

5. Een GenericConverter

EEN GenericConverter biedt ons meer flexibiliteit om een Converter voor een meer generiek gebruik ten koste van het verlies van enige vorm van veiligheid.

Laten we eens kijken naar een voorbeeld van het converteren van een Geheel getal, Dubbele, of een Draad naar een BigDecimal waarde.We hoeven er geen drie te schrijven Converters hiervoor. Een eenvoudige GenericConverter zou het doel kunnen dienen.

De eerste stap is om Spring te vertellen welke soorten conversie worden ondersteund. Dit doen we door een Set van ConvertiblePair:

public class GenericBigDecimalConverter implementeert GenericConverter {@Override public Set getConvertibleTypes () {ConvertiblePair [] paren = nieuw ConvertiblePair [] {nieuw ConvertiblePair (Number.class, BigDecimal.class), nieuw ConvertiblePair (String.class, BigDecimal.class)}; retourneer ImmutableSet.copyOf (paren); }}

De volgende stap is om het converteren() methode in dezelfde klasse:

@Override public Object convert (Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {if (sourceType.getType () == BigDecimal.class) {retourbron; } if (sourceType.getType () == String.class) {String nummer = (String) source; retourneer nieuwe BigDecimal (getal); } else {Number number = (Number) source; BigDecimal geconverteerd = nieuwe BigDecimal (number.doubleValue ()); return geconverteerd.setScale (2, BigDecimal.ROUND_HALF_EVEN); }}

De converteren() methode is zo eenvoudig als het kan zijn. echter, de TypeDescriptor biedt ons een grote flexibiliteit bij het verkrijgen van de details over de bron en het doeltype.

Zoals je misschien al geraden hebt, is de volgende stap om dit te registreren Converter:

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

Dit gebruiken Converter is vergelijkbaar met de andere voorbeelden die we al hebben gezien:

@Test openbare leegte whenConvertingToBigDecimalUsingGenericConverter_thenSuccess () {assertThat (conversionService .convert (Integer.valueOf (11), BigDecimal.class)) .isEqualTo (BigDecimal.valueOf (11.00) .setScale (2, BigD_VENDecimal); 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. Conclusie

In deze tutorial hebben we gezien hoe we het type conversiesysteem van Spring kunnen gebruiken en uitbreiden met verschillende voorbeelden.

Zoals altijd is de volledige broncode voor dit artikel te vinden op GitHub.


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