Я готовлюсь к переносу веб-сервисов SOAP с JAX-RPC на JAX-WS.Он должен быть как можно более плавным:
- WSDL не должен изменяться.
- Новые веб-службы JAX-WS должны использовать ту же реализацию, что и их старые аналоги JAX-RPC (максимумповторное использование кода, без копирования / вставки).
- Новые веб-службы JAX-WS должны иметь возможность работать параллельно со своими старыми аналогами JAX-RPC.
Как это работаетсегодня:
- Существующие WSDL генерируются из классов JAX-RPC @WebService,
- XML-схемы пишутся от руки и компилируются XMLBeans.
- Во время выполненияОбъекты XMLBeans преобразуются в объекты модели написанными от руки * классами конвертера.
Как мы хотим, чтобы это работало после миграции:
- Новая сеть JAX-WSсервисы будут первыми по контракту: интерфейсы конечных точек служб (SEI) будут генерироваться из существующих WSDL.
- Типы XML должны быть привязаны непосредственно к существующим объектам модели.
- Конфигурация привязки должна быть внешней (неиспользовать аннотации).
Я использую цель wsimport из jaxws-maven-plugin (http://www.mojohaus.org/jaxws-maven-plugin/) для генерации кода Java из WSDL.Службы будут развернуты как веб-приложение (не EJB) в WebLogic Server 12.2.1.3.
Я безуспешно пытался использовать:
- Настройки привязки JAX-WS и JAXB
- WLS doc говорит, что «если требуются настройки, Oracle рекомендует [создание внешней привязки] для обеспечения гибкости, сохраняя настройки отдельно от документа WSDL или XML-схемы.»)
- кажется, что япришлось использовать аннотации, и я не смог найти способ использовать XmlAdapters без изменения объектов модели (для добавления XmlJavaTypeAdapter).
- EclipseLink MOXy внешняя привязка (EclipseLink MOXy является привязкой данных по умолчаниюи JAXB-провайдер в WLS12.2.1.3).
- В документе указано, что "EclipseLink MOXy предоставляет (...) возможность использовать внешний файл метаданных для настройки эквивалента аннотаций JAXB без изменения источника Java, на который он ссылается"
- , ноговорит также, что «расширения EclipseLink MOXy могут быть использованы (...) только в сценарии от Java к WSDL».
- на самом деле мне не удалось получить ни инструмент Maven, ни приложение, чтобы использовать этопереплет.
Введите код, он выглядит следующим образом:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>myapp</artifactId>
<packaging>war</packaging>
<groupId>sandbox.jaxws_migration</groupId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>${maven.compiler.source}</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin><artifactId>maven-war-plugin</artifactId><version>3.2.2</version></plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.5</version>
<dependencies>
<dependency>
<groupId>org.glassfish.metro</groupId>
<artifactId>webservices-tools</artifactId>
<version>2.3.1</version>
</dependency>
<!-- see https://java.net/jira/browse/WSIT-1672 -->
<dependency>
<groupId>org.glassfish.metro</groupId>
<artifactId>webservices-rt</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<xadditionalHeaders>true</xadditionalHeaders>
<verbose>true</verbose>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
src / wsdl / hello_world.wsdl
<?xml version='1.0' encoding='UTF-8'?>
<wsdl:definitions name="HelloWorld"
targetNamespace="http://service.myapp/helloworld/"
xmlns:tns ="http://service.myapp/helloworld/"
xmlns:wsdl ="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs ="http://www.w3.org/2001/XMLSchema"
xmlns:soap ="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:p ="http://types.myapp/person/"
>
<wsdl:types>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://service.myapp/helloworld/">
<xs:import namespace="http://types.myapp/person/" schemaLocation="../xsd/person.xsd"/>
<xs:element name="sayHello">
<xs:complexType>
<xs:sequence>
<xs:element name="who" type="p:person"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="sayHelloResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="greetings" type="xs:string">
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<wsdl:message name="sayHello"> <wsdl:part name="p" element="tns:sayHello"/> </wsdl:message>
<wsdl:message name="sayHelloResponse"><wsdl:part name="p" element="tns:sayHelloResponse"/></wsdl:message>
<wsdl:portType name="HelloWorld">
<wsdl:operation name="sayHello">
<wsdl:input message="tns:sayHello"/>
<wsdl:output message="tns:sayHelloResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="HelloWorld" type="tns:HelloWorld">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="sayHello"><soap:operation soapAction="sayHello"/><wsdl:input><soap:body use="literal"/></wsdl:input><wsdl:output><soap:body/></wsdl:output></wsdl:operation>
</wsdl:binding>
<wsdl:service name="HelloWorld">
<wsdl:port name="HelloWorld" binding="tns:HelloWorld">
<soap:address location="http://my.fake.url"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
src / xsd / person.xsd
<?xml version='1.0' encoding='UTF-8'?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
targetNamespace="http://types.myapp/person/"
xmlns:xs ="http://www.w3.org/2001/XMLSchema"
>
<xs:complexType name="person">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="surname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
src / main / java / myapp / service / HelloWorld.java
package myapp.service;
import javax.jws.WebService;
import myapp.legacy.model.LegacyPerson;
@WebService(
endpointInterface = "myapp.service.helloworld.HelloWorld",
wsdlLocation = "wsdl/hello_world.wsdl"
)
public class HelloWorld implements myapp.service.helloworld.HelloWorld {
@Override
public String sayHello(LegacyPerson who) {
return "Hello " + who.getLegacyName() + " " + who.getLegacySurname();
}
}
src / main/java/myapp/legacy/model/LegacyPerson.java
package myapp.legacy.model;
public class LegacyPerson {
private String legacyName;
private String legacySurname;
public String getLegacyName() {
return legacyName;
}
public void setLegacyName(String legacyName) {
this.legacyName = legacyName;
}
public String getLegacySurname() {
return legacySurname;
}
public void setLegacySurname(String legacySurname) {
this.legacySurname = legacySurname;
}
}
src / jaxws / bindings.xml
<jaxb:bindings version="2.0"
xmlns:jaxb ="http://java.sun.com/xml/ns/jaxb"
xmlns:xs ="http://www.w3.org/2001/XMLSchema"
schemaLocation="../xsd/person.xsd"
>
<jaxb:bindings node="/xs:schema/xs:complexType[@name='person']">
<jaxb:class ref="myapp.legacy.model.LegacyPerson"/><!-- Make the SEI use my legacy model, but how should I describe how to bind the data? -->
<!-- This will make wsimport say : "compiler was unable to honor this property customization. It is attached to a wrong place, or its inconsistent with other bindings." -->
<!-- <jaxb:bindings node="//xs:element[@name='name']">
<jaxb:property name="legacyName" />
</jaxb:bindings>-->
</jaxb:bindings>
</jaxb:bindings>
Ссылки