<dependencies>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>4.0.0</version>(1)
</dependency>
<dependency>
<groupId>io.github.threeten-jaxb</groupId>
<artifactId>threeten-jaxb-core</artifactId>
<version>2.1.0</version>(2)
</dependency>
</dependencies>
Eclipse Metro nevie pracovať s balíčkom java.time
.
To je zvláštne, lebo Java 8 je tu od roku 2014, ale vieme to napraviť!
V skutočnosti, s java.time
nevie pracovať knižnica JAXB (Jakarta XML Data Binding), ale tá je súčasťou Metra.
Budeme potrebovať:
-
Javu aspoň 11, ale podpora beží veselo na Jave 17 — poslednom LTS v čase písania článku
-
Eclipse Metro pre Jakarta EE 10 (JAX-WS 4.0)
-
Binding customizations Prispôsobenia prevodu XML na objekty a späť, zvané tiež marshalling, či serializácia.
-
knižnicu ThreeTen, ktorá zavedie podporu pre triedy z
java.time
do JAXB. -
Maven
-
plugin
jaxws-maven-plugin
z Metra
Súbor pre Maven
Do pom.xml
pridajme závislosti na Metre a ThreeTen:
1 | Eclipse Metro pre JAX-WS 4.0 v špecifikácii Jakarta EE 10. |
2 | Knižnica ThreeTen pre podporu „zabudnutých“ tried v JAXB. |
Webservis s dátumami a časmi
Predstavme si webservis, ktorý pracuje s dátumami.
Najprv požiadavka:
<timeRequest xmlns="urn:example:now">anyType</timeRequest>
Odpoveď bude obsahovať aktuálny čas:
<currentLocalDateTime xmlns="urn:example:now">2008-09-29T03:49:45</currentLocalDateTime>
Schéma pre správy
Schéma pokryje požiadavku aj odpoveď:
<schema xmlns="http://www.w3.org/2001/XMLSchema"
version="1.0"
targetNamespace="urn:example:now">
<element name="timeRequest" type="anyType" />
<element name="currentLocalDateTime" type="dateTime" />
</schema>
Schému dáme v projekte do adresára src/wsdl .
Odtiaľ si ju vytiahne mavenovský plugin a tam ju nájde WSDL.
|
WSDL metadáta
WSDL metadáta budú pracovať s uvedenými správami v jedinej operácii: getNow
:
<definitions
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="urn:example:now"
targetNamespace="urn:example:now">
<types>
<schema xmlns="http://www.w3.org/2001/XMLSchema" version="1.0" targetNamespace="urn:example:now"> (1)
<include schemaLocation="now.xsd" /> (2)
</schema>
</types>
<message name="getNow">
<part name="parameters" element="tns:timeRequest"/>
</message>
<message name="getNowResponse">
<part name="parameters" element="tns:currentLocalDateTime"/>
</message>
<portType name="TimeService">
<operation name="getNow"> (3)
<input message="tns:getNow"/>
<output message="tns:getNowResponse"/>
</operation>
</portType>
<binding name="binding" type="tns:TimeService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="getNow">
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="TimeServices">
<port name="port" binding="tns:binding">
<soap:address location="http://localhost:18888/ws/now"/>
</port>
</service>
</definitions>
1 | Schéma pre správy vo formáte XSD. |
2 | Schému zahrnieme pomocou include, keďže menný priestor WSDL (urn:example:now ) a menný priestor schémy sa zhodujú. |
3 | Máme jedinú operáciu getNow . |
Schému dáme v projekte do adresára src/wsdl .
Odtiaľ si ju vytiahne mavenovský plugin.
|
Maven Plugin
Pridajme mavenový plugin, ktorý vygeneruje zdrojáky klienta:
<plugin>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>4.0.0</version>
</plugin>
Generovanie zdrojákov
Vygenerujme zdrojáky klienta:
mvn clean jaxws:wsimport compile
Cieľ wsimport hľadá WSDL v adresári src/wsdl .
|
Uvidíme generované súbory:
target ├── generated-sources │ └── wsimport │ └── example │ └── now │ ├── ObjectFactory.java │ ├── TimeService.java │ └── TimeServices.java
Čo s dátumami?
Trieda TimeService
bude pracovať s dátumami typu XMLGregorianCalendar
:
public XMLGregorianCalendar getNow( (1)
@WebParam(name = "timeRequest", targetNamespace = "urn:example:now", partName = "parameters")
Object parameters);
1 | Metóda vracia XMLGregorianCalendar .
To nám nevyhovuje. |
XML Bindingy
Dodajme do projektu prispôsobenia mapovania XML na objekty a späť.
Dodáme XML Binding Customization. |
Do adresára src/main/jaxws
dodáme jaxb-bindings.xml
.
V tomto adresári ho odhalí Maven plugin. |
<?xml version="1.0" encoding="UTF-8"?>
<bindings version="3.0"
xmlns="https://jakarta.ee/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jaxb https://jakarta.ee/xml/ns/jaxb/bindingschema_3_0.xsd"
> (1)
<globalBindings> (2)
<xjc:javaType
xmlType="xsd:dateTime"
name="java.time.LocalDateTime"
adapter="io.github.threetenjaxb.core.LocalDateTimeXmlAdapter"
/> (3)
</globalBindings>
</bindings>
1 | Dôležité sú:
|
2 | Deklarujeme pravidlá, ktoré platia globálne, pre všetky triedy. |
3 | Deklarujeme pravidlo, ktoré:
|
Element Pozor, existuje totiž aj rovnomenný element z |
Vygenerujme znovu zdrojáky klienta:
mvn clean jaxws:wsimport compile
Uvidíme, že už sa používa java.time.LocalDateTime
.
@XmlJavaTypeAdapter(LocalDateTimeXmlAdapter.class) (2)
@WebMethod
@WebResult(name = "currentLocalDateTime", targetNamespace = "urn:example:now", partName = "parameters")
public LocalDateTime getNow( (1)
@WebParam(name = "timeRequest", targetNamespace = "urn:example:now", partName = "parameters")
Object parameters);
1 | Používa sa LocalDateTime . |
2 | Generátor zdrojákov správne použije adaptér, ktorý sme uviedli v XML súbore. |
Kód pre klienta
Kód pre klienta následne len využije generované zdrojáky:
public class Client {
public static void main(String[] args) {
var serviceLocator = new TimeServices();
TimeService timeService = serviceLocator.getPort();
LocalDateTime now = timeService.getNow(new Object());
System.out.println(now);
}
}
Zdrojové kódy
Zdrojové kódy sú k dispozícii na GitHube, v repozitári novotnyr/jaxws-java-util-time-threeten-client
.