Можно ли перенести существующие веб-сервисы JAX-RPC в JAX-WS без каких-либо модификаций WSDL или модели домена? - PullRequest
0 голосов
/ 26 ноября 2018

Я готовлюсь к переносу веб-сервисов 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>

Ссылки

...