Я использую jaxws-maven-plugin. На мой взгляд, JAX-WS является де-факто стандартной реализацией для WS. У него гораздо лучше сгенерированный код, чем у AXIS, и его проще настраивать и реализовывать. Поддерживается Maven и Spring.
Генерация клиентского кода из файла wsdl, в pom.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<executions>
<execution>
<id>generate-reports-ws-code</id>
<phase>generate-sources</phase>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<!-- This property is used to support having multiple <execution> elements. The plugin has, from some reason, only one timestamp file per the all executions, thus if you have two executions, it doesn't know exactly when to recompile the code. Here we tell it explicitly to have one timestamp file per each execution --> <staleFile>${project.build.directory}/jaxws/stale/.staleFlag.reports</staleFile>
<packageName>com.acme.reports.ws.api</packageName>
<wsdlDirectory>${project.build.directory}/wsdl</wsdlDirectory>
<wsdlFiles>
<wsdlFile>InternalReportsAPIService.wsdl</wsdlFile>
</wsdlFiles>
<verbose>true</verbose>
<sourceDestDir>${wsdl.generated.source.files.dir}</sourceDestDir>
</configuration>
</execution>
</executions>
</plugin>
Интерфейс для создания компонента службы клиента (он не генерируется автоматически):
public interface InternalReportsAPIServiceFactory {
public InternalReportsAPIService createInternalReportsAPIService();
}
Его реализация Бина:
public class InternalReportsAPIServiceFactoryBean implements InternalReportsAPIServiceFactory {
private URL acmeReportsWsdlURL;
private final static QName V1_QNAME = new QName("http://internal.reports.api.acme.net/v1","InternalReportsAPIService");
@Override
public InternalReportsAPIService createInternalReportsAPIService() {
return new InternalReportsAPIService(acmeReportsWsdlURL, V1_QNAME);
}
public void setAcmeReportsWsdlUrl(String acmeReportsWsdlUrl) {
try {
this.acmeReportsWsdlURL = new URL(acmeReportsWsdlUrl);
} catch (MalformedURLException ex) {
throw new RuntimeException("Acme Reports WSDL URL is bad: "+ex.getMessage(), ex);
}
}
}
Идея в этом bean-компоненте (используемом как Spring bean-компоненте) состоит в том, чтобы иметь синглтон для генерации кода службы клиента. Для этого требуется два ввода: URL-адрес WSDL, то есть фактический URL-адрес сервера, который реализует WSDL. Код клиентского сервиса при создании отправляет запрос на получение WSDL по указанному URL. Затем он создает WSDL на основе аннотаций, находящихся в автоматически сгенерированном коде, и сравнивает его. Я считаю, что это сделано, чтобы убедиться, что вы работаете с верной версией сервера.
Итак, я поместил URL-адрес в файл свойств, доступный для моего приложения, поэтому я инициализирую его в файле контекста приложения Spring.
Вот пример использования фабрики для генерации сервиса и последующего его использования:
InternalReportsAPIService internalReportsAPIService = acmeReportsWSFactory.createInternalReportsAPIService();
InternalReportsAPI port = internalReportsAPIService.getInternalReportsAPIPort();
Отсюда, просто используйте переменную порта для вызова любой операции, доступной в wsdl.