Inleiding tot Smooks

1. Overzicht

In deze tutorial introduceren we het Smooks-framework.

We beschrijven wat het is, zetten de belangrijkste functies op een rij en leren uiteindelijk hoe we enkele van de meer geavanceerde functies kunnen gebruiken.

Laten we allereerst kort uitleggen wat het raamwerk moet bereiken.

2. Smooks

Smooks is een raamwerk voor gegevensverwerkingstoepassingen - het omgaan met gestructureerde gegevens zoals XML of CSV.

Het biedt zowel API's als een configuratiemodel waarmee we transformaties tussen vooraf gedefinieerde formaten kunnen definiëren (bijvoorbeeld XML naar CSV, XML naar JSON en meer).

We kunnen ook een aantal tools gebruiken om onze mapping in te stellen - inclusief FreeMarker- of Groovy-scripts.

Naast transformaties levert Smooks ook andere functies zoals berichtvalidatie of gegevenssplitsing.

2.1. Belangrijkste kenmerken

Laten we eens kijken naar de belangrijkste use-cases van Smooks:

  • Berichtconversie - transformatie van gegevens van verschillende bronformaten naar verschillende uitvoerformaten
  • Berichtverrijking - het bericht invullen met aanvullende gegevens, die afkomstig zijn van een externe gegevensbron, zoals een database
  • Gegevens splitsen - grote bestanden (GB's) verwerken en ze opsplitsen in kleinere
  • Java-binding - het samenstellen en vullen van Java-objecten uit berichten
  • Berichtvalidatie - het uitvoeren van validaties zoals regex, of zelfs het maken van uw eigen validatieregels

3. Initiële configuratie

Laten we beginnen met de Maven-afhankelijkheid die we aan ons moeten toevoegen pom.xml:

 org.milyn milyn-smooks-all 1.7.0 

De nieuwste versie is te vinden op Maven Central.

4. Java-binding

Laten we nu beginnen door ons te concentreren op het binden van berichten aan Java-klassen. We zullen hier een eenvoudige XML naar Java-conversie doorlopen.

4.1. Basisconcepten

We beginnen met een eenvoudig voorbeeld. Beschouw de volgende XML:

 771 IN_PROGRESS 

Om deze taak met Smooks te volbrengen, moeten we twee dingen doen: de POJO's voorbereiden en de Smooks-configuratie.

Laten we eens kijken hoe ons model eruit ziet:

openbare klasse Order {private Date creationDate; privé lang nummer; privé status status; // ...} 
openbare opsomming Status {NEW, IN_PROGRESS, FINISHED}

Laten we nu verder gaan met Smooks-toewijzingen.

In wezen zijn de toewijzingen een XML-bestand dat transformatielogica bevat. In dit artikel gebruiken we drie verschillende soorten regels:

  • Boon - definieert de toewijzing van een betonnen gestructureerde sectie aan de Java-klasse
  • waarde - definieert de mapping voor de specifieke eigenschap van de boon. Kan meer geavanceerde logica bevatten, zoals decoders, die worden gebruikt om waarden toe te wijzen aan bepaalde gegevenstypen (zoals datum of decimaal formaat)
  • wiring - stelt ons in staat om een ​​boon te verbinden met andere bonen (bijvoorbeeld Leverancier bean zal worden aangesloten Bestellen Boon)

Laten we eens kijken naar de toewijzingen die we in ons geval hier zullen gebruiken:

      jjjj-MM-dd 

Nu de configuratie klaar is, gaan we proberen te testen of onze POJO correct is opgebouwd.

Eerst moeten we een Smooks-object construeren en invoer-XML als een stroom doorgeven:

openbare orde converOrderXMLToOrderObject (tekenreekspad) gooit IOException, SAXException {Smooks smooks = nieuwe Smooks (this.class.getResourceAsStream ("/ smooks-mapping.xml")); probeer {JavaResult javaResult = new JavaResult (); smooks.filterSource (nieuwe StreamSource (this.class .getResourceAsStream (pad)), javaResult); return (Order) javaResult.getBean ("order"); } eindelijk {smooks.close (); }}

En stel ten slotte vast of de configuratie correct is uitgevoerd:

@ Test openbare ongeldig gegevenOrderXML_whenConvert_thenPOJOsConstructedCorrectly () gooit uitzondering {XMLToJavaConverter xmlToJavaOrderConverter = nieuwe XMLToJavaConverter (); Bestel order = xmlToJavaOrderConverter .converOrderXMLToOrderObject ("/ order.xml"); assertThat (order.getNumber (), is (771L)); assertThat (order.getStatus (), is (Status.IN_PROGRESS)); assertThat (order.getCreationDate (), is (nieuwe SimpleDateFormat ("jjjj-MM-dd"). parse ("2018-01-14"));}

4.2. Geavanceerde binding - Verwijzen naar andere bonen en lijsten

Laten we ons vorige voorbeeld uitbreiden met leverancier en bestelartikelen tags:

 771 IN_PROGRESS Bedrijf X 1234567 1 PX1234 9.99   1 RX990 120.32   

En laten we nu ons model updaten:

openbare klasse Order {// .. private leverancier leverancier; privélijstitems; // ...}
openbare klasse Item {privé String-code; privé Dubbele prijs; private Integer hoeveelheid; // ...} 
openbare klasse Leverancier {privé Stringnaam; privé String phoneNumber; // ...}

We moeten ook de configuratie-mapping uitbreiden met de leverancier en item bean definities.

Merk op dat we ook gescheiden hebben gedefinieerd items boon, die alles zal bevatten item elementen in ArrayList.

Ten slotte zullen we Smooks gebruiken bedrading attribuut, om het allemaal samen te bundelen.

Bekijk hoe toewijzingen er in dit geval uit zullen zien:

      jjjj-MM-dd 

Ten slotte voegen we een paar beweringen toe aan onze vorige test:

assertThat (order.getSupplier (), is (nieuwe leverancier ("Bedrijf X", "1234567"))); assertThat (order.getItems (), containsInAnyOrder (nieuw item ("PX1234", 9.99,1), nieuw item ("RX990", 120.32,1)));

5. Berichtenvalidatie

Smooks wordt geleverd met een validatiemechanisme op basis van regels. Laten we eens kijken hoe ze worden gebruikt.

De definitie van de regels wordt opgeslagen in het configuratiebestand, genest in het ruleBases tag, die er veel kan bevatten ruleBase elementen.

Elk ruleBase element moet de volgende eigenschappen hebben:

  • naam - unieke naam, alleen gebruikt ter referentie
  • src - pad naar het regelbronbestand
  • provider - volledig gekwalificeerde klassenaam, die implementeert RuleProvider koppel

Smooks wordt standaard geleverd met twee providers: RegexProvider en MVELProvider.

De eerste wordt gebruikt om individuele velden in regex-achtige stijl te valideren.

De tweede wordt gebruikt om meer gecompliceerde validatie uit te voeren in de globale reikwijdte van het document. Laten we ze in actie zien.

5.1. RegexProvider

Laten we gebruiken RegexProvider om twee dingen te valideren: het formaat van de klantnaam en het telefoonnummer. RegexProvider als bron is een Java-eigenschappenbestand vereist, dat zou regex-validatie op sleutelwaarde-wijze moeten bevatten.

Om aan onze vereisten te voldoen, gebruiken we de volgende instellingen:

supplierName = [A-Za-z0-9] * leverancierPhone = ^ [0-9 \ - \ +] {9,15} $

5.2. MVELProvider

We zullen gebruiken MVELProvider om te valideren of de totale prijs voor elk bestel item is minder dan 200. Als bron bereiden we een CSV-bestand voor met twee kolommen: regelnaam en MVEL-expressie.

Om te controleren of de prijs klopt, hebben we de volgende invoer nodig:

"max_total", "orderItem.quantity * orderItem.price <200,00"

5.3. Validatieconfiguratie

Zodra we de bronbestanden hebben voorbereid voor ruleBasesgaan we verder met het implementeren van concrete validaties.

Een validatie is een andere tag in de Smooks-configuratie, die de volgende attributen bevat:

  • executeOn - pad naar het gevalideerde element
  • naam - verwijzing naar de ruleBase
  • onFail - specificeert welke actie wordt ondernomen als validatie mislukt

Laten we validatieregels toepassen op ons Smooks-configuratiebestand en kijken hoe het eruit ziet (merk op dat als we de MVELProvider, we zijn gedwongen om Java-binding te gebruiken, dus daarom hebben we de vorige Smooks-configuratie geïmporteerd):

Nu de configuratie gereed is, gaan we proberen te testen of validatie mislukt op het telefoonnummer van de leverancier.

Nogmaals, we moeten bouwen Smooks object en geef invoer-XML door als een stroom:

public ValidationResult validate (String path) gooit IOException, SAXException {Smooks smooks = nieuwe Smooks (OrderValidator.class .getResourceAsStream ("/ smooks / smooks-validation.xml")); probeer {StringResult xmlResult = new StringResult (); JavaResult javaResult = nieuw JavaResult (); ValidationResult validationResult = nieuw ValidationResult (); smooks.filterSource (nieuwe StreamSource (OrderValidator.class .getResourceAsStream (pad)), xmlResult, javaResult, validationResult); terugkeer validationResult; } eindelijk {smooks.close (); }} 

En stel ten slotte vast, als er een validatiefout is opgetreden:

@Test openbare ongeldigheid gegevenIncorrectOrderXML_whenValidate_thenExpectValidationErrors () gooit uitzondering {OrderValidator orderValidator = nieuwe OrderValidator (); ValidationResult validationResult = orderValidator .validate ("/ smooks / order.xml"); assertThat (validationResult.getErrors (), hasSize (1)); assertThat (validationResult.getErrors (). get (0) .getFailRuleResult (). getRuleName (), is ("supplierPhone")); }

6. Berichtconversie

Het volgende dat we willen doen, is het bericht van het ene formaat naar het andere converteren.

In Smooks wordt deze techniek ook wel sjablonen genoemd en het ondersteunt:

  • FreeMarker (voorkeursoptie)
  • XSL
  • Draad sjabloon

In ons voorbeeld gebruiken we de FreeMarker-engine om XML-berichten te converteren naar iets dat erg lijkt op EDIFACT, en we maken zelfs een sjabloon voor het e-mailbericht op basis van XML-volgorde.

Laten we eens kijken hoe we een sjabloon voor EDIFACT kunnen voorbereiden:

UNA: +.? 'UNH + $ {order.number} + $ {order.status} + $ {order.creationDate? Date}' CTA + $ {supplier.name} + $ {supplier.phoneNumber} 'LIN + $ {item.quantity} + $ { item.code} + $ {item.price} ' 

En voor het e-mailbericht:

Hallo, ordernummer # $ {order.number} aangemaakt op $ {order.creationDate? Date} heeft momenteel de status $ {order.status}. Overweeg om contact op te nemen met de leverancier "$ {supplier.name}" met telefoonnummer: "$ {supplier.phoneNumber}". Bestelitems: $ {item.quantity} X $ {item.code} (totale prijs $ {item.price * item.quantity}) 

De Smooks-configuratie is deze keer erg basic (vergeet niet om de vorige configuratie te importeren om Java-bindingsinstellingen te importeren):

    /path/to/template.ftl 

Deze keer moeten we gewoon een StringResult naar Smooks engine:

Smooks smooks = nieuwe Smooks (config); StringResult stringResult = nieuwe StringResult (); smooks.filterSource (nieuwe StreamSource (OrderConverter.class .getResourceAsStream (pad)), stringResult); return stringResult.toString ();

En we kunnen het natuurlijk testen:

@Test openbare ongeldig gegevenOrderXML_whenApplyEDITemplate_thenConvertedToEDIFACT () gooit uitzondering {OrderConverter orderConverter = nieuwe OrderConverter (); String edifact = orderConverter.convertOrderXMLtoEDIFACT ("/smooks/order.xml"); assertThat (edifact, is (EDIFACT_MESSAGE)); }

7. Conclusie

In deze zelfstudie hebben we ons gericht op het converteren van berichten naar verschillende indelingen, of ze omzetten in Java-objecten met Smooks. We hebben ook gezien hoe u validaties kunt uitvoeren op basis van regex- of bedrijfslogica-regels.

Zoals altijd is alle code die hier wordt gebruikt, te vinden op GitHub.


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