3

SOAP, JAX-WS, Metro a serializácia dátumov a časov

 1 year ago
source link: https://novotnyr.github.io/scrolls/jax-ws-a-praca-s-casom-java-time/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

SOAP, JAX-WS, Metro a serializácia dátumov a časov

SOAP, JAX-WS, Metro a serializácia dátumov a časov

2022/10/31

Vytvorme SOAP web service pomocou JAX-WS 4.0 (Jakarta XML Web Services) a Eclipse Metro.

Ak používame základné dátové typy, všetko je v poriadku. Vo chvíli, keď začneme používať dátumy a časy z knižnice java.time, nastanú problémy.

Príprava pom.xml

Pripravme si mavenovský projekt, kde dodajme závislosti na Metre a podporu pre Javu 17.

pom.xml
1 Dodajme závislosť na Eclipse Metro.
2 Explicitný woodstox-core uvádzame kvôli bezpečnostnej chybe v Eclipse Metro 4.0, kde použijeme novšiu verziu tejto knižnice s opravenou chybou.
3 Použijeme Javu 17.

Webservis v SOAP

Pridajme si ukážkový SOAPový webservis, vrátane metódy main():

TimeService.java
1 Metóda vracia objekt s dátumom a časom java.time.LocalDateTime.
2 Pripravíme si endpoint a publikujeme ho.

Ako vyzerá WSDL?

WSDL a jeho stav? Jedným slovom: nie veľmi dobre.

Pozrime sa na adresu http://localhost:18888/ws/now?xsd=1 a uvidíme zvláštnu schému:

Operácia getNowResponse vracia akýsi XML dátový typ localDateTime, ktorá je definovaný ako prázdna sekvencia.

JAX-WS síce vygenerovalo WSDL, ale nikto ho nevie normálne spracovať.

Ak by sme skúsili požiadavku v SoapUI, dostaneme odpoveď:

1 Element return rozhodne neobsahuje nič užitočné, hoci by sme čakali aktuálny dátum.
JAX-WS nevie normálne pracovať s objektami z balíčka java.time.

Knižnica threeten-jaxb, dostavte sa do projektu!

Prevod medzi objektami a XML v Jakarta XML Web Services zabezpečuje samostatná špecifikácia JAXB (Jakarta XML Binding).

Súčasťou Metra je aj jej referenčná implementácia.

Knižnica threeten-jaxb predstavuje XML adaptéry pre konverziu tried, ktoré sa nedostali do jadra referenčnej implementácie JAXB`. Špeciálne je tam podpora pre dátumy a časy.

Dodajme do pom.xml závislosť:

pom.xml

Plán rekonštrukcie

Na to, aby sme to rozbehali korektne, potrebujeme 4 kroky:

  1. pridať závislosť na Three Ten: to sme spravili

  2. vytvoriť vlastnú doménovú triedu, v ktorej vrátime aktuálny čas

  3. vracať z SOAP operácie doménovú triedu

  4. pripraviť anotáciu, ktorá prevedie všetky LocalDateTime na normálnu konštrukciu v XML

Vlastná doménová trieda

Vytvorme vlastnú doménovú triedu.

CurrentLocalDateTime.java

Trieda je úplne bežná, neobsahuje nič špeciálne.

Úprava operácie v SOAP webservise

Operácia v SOAPovej webservice nech vracia našu doménovú triedu:

TimeService.java
1 Zrazu vraciame doménový objekt.

Zapojenie XML adaptéra na prevod

V balíčku com.github.novotnyr.soap vytvorme súbor package-info.java, kde zavedieme pravidlo pre prevody medzi LocalDateTime cez adaptér LocalDateTimeXmlAdapter z knižnice ThreeTen na reťazce.

1 Zavedieme adaptér LocalDateTimeXmlAdapter.class, ktorý sa použije na serializáciu a deserializáciu.
2 Budeme pracovať s objektami typu LocalDateTime.
Anotácia je nad celým balíčkom s našim serverom.

Reštart webservisy

Reštartnime webservisu a pozrime sa, ako vyzerá XML schéma.

Navštívme opäť http://localhost:18888/ws/now?xsd=1 a uvidíme:

filename.xml
1 Výstupný element je teraz typu currentLocalDateTime, ktorý sa rozoberie v ďalšom kroku.
2 Tento dátový typ v XML schéme obsahuje jediný atribút: dateTime typu String, ktorý môže byť vynechaný (minOccurs=0).
Vďaka adaptéru sa budú dátumy a časy typu LocalDateTime prevádzať na reťazce v XML.

Ak aktualizujeme definíciu SOAPovej služby v SoapUI, uvidíme inú odpoveď:

1 Dátumy a čas už chodia ako reťazce vo formáte ISO-8601.

Ako by vyzeral klient?

Ak by sme si vygenerovali SOAP klienta v Jave na základe WSDL, uvideli by sme triedu, kde je dátum a čas reprezentovaný ako reťazec:

CurrentLocalDateTime.java
1 Dátum a čas je reprezentovaný ako reťazec. Je to presne preto, že v XML schéme máme uvedený dátový typ xsd:string.

Ako upraviť XML schému?

Vieme upraviť serverovský kód tak, aby v schéme XML vo WSDL vracal dátum a čas? Veď existuje primitívny dátový typ dateTime!

Na toto musíme dodať ďalšiu anotáciu do serverovskej doménovej triedy.

CurrentLocalDateTime.java
1 Do gettera doménového objektu dodáme anotáciu @XmlSchemaType. Uvedieme dve vlastnosti:
  • name: názov dátového typu zo XML schémy. Uvádzame ho ako reťazec.

  • type: dátový typ z Javy, na ktorý sa namapuje typ z XML schémy.

Anotáciu dávame nad getter, nie nad inštančnú premennú, pretože inak uvidíme chybu s duplicitnou deklaráciou atribútu dateTime.

Reštartnime SOAP server a pozrime si schému pre XSD na http://localhost:18888/ws/now?xsd=1.

Uvidíme pozitívne zmeny:

1 Element dateTime je už zo štandadného primitívneho typu zo XML schémy xs:dateTime a nie reťazec!

Pregenerovanie XML klienta

Ak pregenerujeme klienta cez JAX-WS 4.0, uvidíme zmeny:

CurrentLocalDateTime.java
1 Generátor klienta vytvoril premennú typu XMLGregorianCalendar
2 Premennú namapoval na dátový typ dateTime zo XML schémy.

V kóde potom vieme previesť XMLGregorianCalendar na LocalDateTime:

1 Získame surový XML objekt s dátumom a časom.
2 Prevedieme ho na LocalDateTime.
Ak by sme sa chceli zbaviť komplikovaného ručného prevodu, museli by sme použiť mechanizmus JAXB Bindings, resp. XJC Bindings, ktorý je ale už mimo záber tohto článku.

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK