Статьи

Пример использования SOA: интеграция форм Adobe LiveCycle с использованием JBossWS

JBossWS — это инфраструктура, которая реализует JAX-WS 2.0 (замену более ранней спецификации JAX-RPC) и определяет модель программирования / времени выполнения для реализации веб-сервисов как механизм удаленного взаимодействия для распределенных сервис-ориентированных архитектур [REF-1]. JBossWS ориентирован на платформу Java SE 6 / EE 5 и интегрируется с большинством текущих и более ранних версий JBoss Application Server. В этой статье я продемонстрирую, как легко использовать инфраструктуру JBossWS для использования возможностей аннотаций Java 5, а также метаданных, связанных с конечной точкой, предоставляемых аннотациями JSR 181, для разработки, предоставления, использования и защиты сервиса.Аннотации гарантируют, что исходный код будет довольно простым и понятным POJO, при этом ответственность за обработку ложится на инструменты JBossWS на клиенте и сервере для создания контракта и инфраструктуры, необходимых во время развертывания и выполнения. Чтобы проиллюстрировать эти концепции, я использовал пример реальной службы, которая позволяет различным системам в нашей организации (государственному агентству) интегрироваться с централизованной системой форм для извлечения, доставки и обработки интеллектуальных документов конечным пользователям и от них. ,Ризван Ахмед, опубликованный в журнале SOA Magazine в мае 2009 г.

Введение
В качестве неотъемлемой части повседневной деятельности нашему агентству необходимо управлять сотнями различных форм в различных функциональных областях бизнеса — от регистрации клиентов и подачи заявок до федеральных налоговых отчетов и отчетности о соответствии. Программное обеспечение Adobe LiveCycle® Forms позволяет нам создавать и развертывать шаблоны форм на основе XML, отображаемые в формате PDF и HTML, во время выполнения для использования с программным обеспечением Adobe Reader® или любым стандартизированным веб-браузером. Визуальная точность PDF облегчает использование и имеет стандартизированные, легко читаемые форматы документов для простого архивирования и индексации в системе управления документами или изображениями.

Принятие хорошо спроектированных, автоматизированных, безопасных процессов форм, единообразно интегрированных с унаследованными внутренними системами и общедоступными онлайн-системами, было определено как ключ к повышению точности данных, сокращению времени предоставления услуг и сокращению административных расходов и ручного вмешательства / ввода данных. Использование повсеместного использования XML для обмена данными и новых стандартов веб-сервисов позволяет нам создавать централизованные компоненты и процессы многократного использования для использования внешними системами вызова.

О формах Adobe LiveCycle

Модуль сервера форм Adobe LiveCycle (в дальнейшем именуемый FSM) предоставляет набор сервисов и клиентских API, которые можно использовать для создания интерактивных приложений, использующих возможности предварительного заполнения данных для визуализации предварительно заполненных форм в формате PDF или HTML на клиентском устройстве. например, браузер и сбор данных из отправленных форм для интеграции с основными внутренними системами. FSM предоставляет конечную точку веб-службы Axis без состояния и конечную точку EJB для визуализации содержимого формы и обработки отправленных форм. Обе конечные точки доступны только через клиентские API-интерфейсы FSM, которые абстрагируют детали фактического вызова вызовов RMI SOAP / EJB за объектами фабрики. Когда служба FSM получает запрос на форму,он использует набор преобразований для объединения данных с дизайном формы, а затем доставляет форму в формате, который наилучшим образом соответствует возможностям представления и заполнения формы целевого браузера. Затем может произойти обработка отправки формы, которая в основном включает использование клиентских API FSM для обработки межстраничной навигации или отправки данных формы (которые могли быть обновлены на этом этапе) из клиентского браузера.

Типичные случаи использования
A. Клиентская система рендеринга формы

Идея варианта использования заключается в том, что вызывающему приложению потребуется извлечь форму, предварительно заполненную значениями полей, полученными из внешнего источника данных. Вызовите метод renderForm () API клиента FSM (см. Листинг 1). Вам потребуется передать номер дизайна формы, параметр предпочтения (HTML или PDF), байтовый массив, содержащий XML-представление имени и значений поля формы, абсолютный путь к хранилищу дизайнов форм в файловой системе сервера, на котором размещается служба FSM и целевой URL-адрес, который определяет действие веб-формы для содержимого отображаемой HTML-формы (этот URL-адрес обычно сопоставляется с сервлетом или классом действия, инкапсулирующим логику обработки отправки формы — см. листинг 2).Результирующий набор представляет собой предварительно заполненное отображаемое содержимое HTML в виде строки или содержимое PDF в виде двоичного байтового массива, который затем можно отправить обратно в ResponseStream в браузер для отображения.

Листинг 1:

// Create an FSM Endpoint proxy
Properties props = new Properties();
props.setProperty(FormServerFactory.CLASSNAME_PROP, "com.adobe.formServer.client.SOAPClient");
props.setProperty(FormServerFactory.ENDPOINT_PROP, soapEndpoint); // FSM Axis WS endpoint

IFormServer ifs = FormServerFactory.create(props);

IOutputContext ioc =
ifs.renderForm
(
sFormQuery, // Desired form design number to render
sFormPreference, // Preference option eg. HTML/PDF
cData, // XML representation of data that requires merging into form
"OutputType=0",
sUserAgent, // user-agent string from the calling browser
sApplicationWebRoot, // URL context of the Adobe FSM
sTargetURL, // URL of the target action the rendered form will submit to
sContentRootURI, // Absolute path to the form designs repository
null
);

// Rendered form content as HTML if requested in preference option
String formContent = ioc.getOutputString();

// Alternately, rendered form content as PDF
byte[] generatedForm = ioc.getOutputContent();

B.

Передача формы обработки клиентской системы Идея варианта использования в данном случае заключается в том, что вызывающему приложению потребуется отправить данные либо в результате навигации по страницам, либо использовать форму для отправки данных обратно в источник данных. Вызовите метод API клиента FSM processFormSubmission (), передав в массив байтов отправленные данные поля формы (см. Листинг 2). После определения состояния обработки отправленной формы, то есть, если пользователь просто запросил навигацию по странице, то вновь запрошенное содержимое HTML отправляется обратно.

Листинг 2 :

// Create an FSM Endpoint proxy
Properties props = new Properties();
props.setProperty(FormServerFactory.CLASSNAME_PROP, "com.adobe.formServer.client.SOAPClient");
props.setProperty(FormServerFactory.ENDPOINT_PROP, soapEndpoint); // FSM Axis WS endpoint

IFormServer ifs = FormServerFactory.create(props);
byte[] byteArray = inputObj.getContentArray().getByteArray(); // form field submitted data

IOutputContext ioc = ifs.processFormSubmission(byteArray,"HTTP_REFERER=referrer&HTTP_CONNECTION=keep-alive&CONTENT_TYPE=
application/x-www-form-urlencoded",null,"exportDataFormat=XDP&CacheEnabled=False&XMLData=true");

String formContent = ioc.getOutputString();

Проблемная область

У нас есть описанные выше варианты использования (A. и B.), которые отлично работают, когда клиентские API FSM и зависимые библиотеки включены в вызывающее приложение. Но что, если, как и в нашем случае, у нас есть несколько систем, которым необходимо использовать службы Adobe Form в контексте их отдельных приложений. Зачем нам нужно включать клиентские API, библиотеки и вызовы методов в каждое отдельное приложение, которому требуется доступ к службам, предоставляемым FSM?

Следуя принципам бережливой сервис-ориентированной архитектуры [REF-2], решение состоит в том, чтобы создать простой сервисный фасад JAX-WS, вызываемый из любого внешнего приложения. Цель состоит в том, чтобы все детали реализации того, как происходит рендеринг и обработка форм, скрыты в реализации сервиса, и все клиенты (включая различные корпоративные приложения), которым необходим доступ, могут легко искать и использовать предоставляемые сервисы через опубликованные контракты (определения WSDL). в модели концентратора и луча, которую можно легко превратить в модель на основе шины сообщений для лучшей интеграции ИТ-среды.

Пожалуйста, обратитесь к рисунку 1, который показывает диаграмму компонентов высокого уровня для нашего внутреннего ландшафта. Системам EES (Электронные услуги работодателя), Доступу участника и PAC (Платежи и претензии) необходим доступ к услугам, предоставляемым Adobe LiveCycle FSM. Поскольку эти службы доступны только через клиентские API-интерфейсы FSM, специальный код рендеринга и обработки отправки формы заключен в конечную точку веб-службы JSX-WS Stateless Session Bean (SLSB), упакованную в специальное приложение Forms. Внешние системы также нуждаются в автоматическом заполнении форм на основе регистрационных номеров и номеров социального страхования с конкретной информацией о клиенте (например, именем, адресом и другой демографической информацией), доступной в приложении ScrsCommon CRM.Вместо того, чтобы интегрировать поиск данных в ScrsCommon в каждое отдельное приложение и затем передать эти данные в качестве параметров в службу Forms JAX-WS, более оптимальным является создание реализации службы JAX-WS для функции поиска данных ScrsCommon и ссылка на нее как на домен объект в реализации сервиса Forms.

 Рисунок 1: Компонентная схема высокого уровня нашего внутреннего ландшафта

Создание дружественных для разработчиков веб-сервисов с помощью JBossWS

Спецификация JAX-WS, реализованная JBossWS [REF-1], представляет собой высокоуровневый API, который не требует от вас много знаний о метаданных веб-сервисов (определения WSDL), которые определяют типы XML (схемы) для каждой части сообщения, используемой в запросах и ответах операций сервиса. Простота разработки с использованием этого API может быть измерена тем фактом, что весь уровень XML скрыт от разработчиков, которые вместо этого просто работают с объектами, сгенерированными инструментами JBossWS, которые инкапсулируют всю работу по созданию сообщений SOAP, вызову сервиса и анализу ответ. JAX-WS не имеет своего собственного механизма привязки или (отмены) сортировки и делегирует все преобразования из объекта Java в XML и наоборот в API JAXB2.0.

Существует два основных подхода к разработке Web-сервисов с помощью JBossWS:

A. Сначала контракт (сверху вниз).

Разработайте определение WSDL вручную, используя редактор XML или IDE. Используйте инструменты JBossWS, такие как wsconsume, для генерации артефактов переносимых серверов и клиентов. Чтобы избежать ненужных трудностей, возникающих при создании документа WSDL вручную, этот подход следует использовать только для изменения или замены только существующих служб и контрактов.

Б. Контракт последний (снизу вверх)

Создайте интерфейс конечной точки службы (SEI) и классы реализации конечной точки в виде исходных файлов Java. Используйте инструмент JBossWS wsprovide для передачи в SEI для генерации определения WSDL и переносимых артефактов на стороне клиента. Как правило, быстрее разрабатывается, чем Top Down, и его следует использовать, когда вы хотите предоставить новую услугу или контракт.

Инструменты, сгенерированные классы значений client, service и JAXB 2.0, сильно аннотированы. Использование аннотаций вместе с инструментами времени выполнения, которые обеспечивают внедрение зависимостей, к счастью, скрыты в инфраструктуре обработки, упрощают разработку и сопровождение для разработчиков (другими словами, больше нет раздутого кода, причудливых дескрипторов развертывания и проблем переносимости).

Конечные точки JBossWS

Как правило, конечная точка веб-службы является компонентом на стороне сервера, который принимает сообщения SOAP, обрабатывает их или делегирует дополнительную обработку бизнес-делегату и возвращает ответ на сообщение SOAP. В JAX-WS могут быть 2 различных типа конечных точек веб-службы: POJO (простые старые объекты Java) и EJB3 SLSB (сессионный компонент без сохранения состояния).

Конечная точка POJO будет развернута в виде сервлета и упакована в файл WAR, а конечная точка SLSB будет развернута как EJB3-компонент и упакована в JAR (или EAR). Сервер (JBoss) автоматически генерирует и публикует абстрактный контракт (определение WSDL + схема) для использования клиентом. Успешно развернутая служба будет отображаться в диспетчере конечных точек службы JBossWS (http: // hostname: 8080 / jbossws / services). Здесь вы также найдете ссылки на сгенерированный документ WSDL.

Интерфейс конечной точки сервиса

Все сервисы JAX-WS обычно реализуют собственный интерфейс конечной точки сервиса Java (SEI), который обеспечивает высокоуровневую абстракцию, ориентированную на Java, которая скрывает детали преобразования между объектами Java и их представлениями XML для использования в сообщениях на основе XML. Обратите внимание, что в некоторых случаях желательно, чтобы службы могли работать на всем уровне сообщений SOAP или уровня полезной нагрузки, для которых вы бы использовали интерфейс провайдера, который предлагает альтернативу SEI. Если вашей конечной точкой является SLSB, удаленный интерфейс для нее может служить SEI.

Создание JBossWS SEI и реализация Bean для рендеринга формы

Аннотация @WebService (javax.jws.WebService) указывает, что класс Java реализует веб-службу. При использовании в интерфейсе Remote SLSB (украшенном аннотацией @Remote) он служит интерфейсом конечной точки веб-службы (см. Листинг 3). Имя элемента отображается на элемент wsdl: portType в документе WSDL. TargetNamespace задает пространство имен, в котором будет определяться служба. @SOAPBinding определяет атрибут стиля детали реализации из домена Java.

Хотя существует несколько доступных стилей, основанных на требованиях совместимости и необходимости бизнес-модели, мне особенно нравится использовать стиль Document / Literal Bare (SOAPBinding.ParameterStyle.BARE), который использует Java Bean для представления всей полезной нагрузки [REF-3] и Это особенно полезно при работе с одним параметром / возвращаемым значением, если вы не хотите загромождать свои сервисные методы дополнительными аннотациями и несколькими элементами параметров.

В этом примере я создал интерфейс конечной точки службы, который возвращает запрошенный дизайн формы (переданный в качестве параметра в объекте FormClientDemographicsInput), предварительно заполненный демографической информацией о клиенте / клиенте из внешней ссылки на веб-службу. Все детали реализации того, как форма визуализируется, инкапсулированы в bean-компоненте, который просто возвращает объект FormClientDemographicsOutput, содержащий HTML-содержимое визуализированной формы в виде строки или содержимое PDF в виде двоичного байтового массива.

Листинг 3:

// Service Endpoint Interface SEI Class
@Remote
@WebService(name = "FormClientDemographics", targetNamespace = "http://scrs.forms.service")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface FormClientDemographics {
@WebMethod
public FormClientDemographicsOutput callRenderForm(FormClientDemographicsInput inputObj) throws FormException;
}

In the implementation class (refer to Listing 4), the @Stateless annotation signifies a Stateless Session Bean, the @WebService annotation must have the following properties: endpointInterface — fully qualified class name of the SEI, name — SEI name mappable to the wsdl:portType and serviceName — mappable to the wsdl:service (please refer to the relevant WSDL document elements in Listing 5). The @WebContext defines the application context root that the endpoint bean will be available at. The @Security and @RolesAllowed annotations are addressed in the Security section of this article. The @WebServiceRef is used to declare a runtime injectable reference (resource in the Java EE5 sense) to the CustomerLookupService implementation in the ScrsCommon system, the domain data of which is used for pre-filling the form content.

Listing 4:

// SLSB Implementation Class
@Stateless
@WebService(endpointInterface = "scrs.forms.service.FormClientDemographics", name = "FormClientDemographics", serviceName = "FormClientDemographicsService")
@WebContext(contextRoot = "/formsWS", authMethod="BASIC")
@SecurityDomain("JBossWS")
@RolesAllowed("friend")
@BindingType(value = "http://schemas.xmlsoap.org/wsdl/soap/http?mtom=true")
public class FormClientDemographicsBean implements FormClientDemographics
{
// Runtime injectable WS Reference to the CustomerLookupService on the ScrsCommon system
@WebServiceRef(wsdlLocation = "META-INF/wsdl/CustomerLookupService.wsdl")
private CustomerLookupService customerLookupService;
private CustomerLookup customerPort;

public CustomerLookup getCustomerLookupPort() {
return customerLookupService.getCustomerPort();
}

public FormClientDemographicsOutput callRenderForm(FormClientDemographicsInput inputObj) throws FormException
{
try{
byte[] cData = getCustomerLookupPort().getCustomerData(inputObj.getInputSSN());
// Implementation of the Adobe FSM renderForm() specific logic as shown in Listing 1
...
} catch (Exception ex) {
throw new FormException(..);
}
}
}

 

Listing 5:

<portType name='FormClientDemographics'>
<operation name='callRenderForm' parameterOrder='callRenderForm'>
<input message .../>
<output message ../>
<fault message ../>
</operation>
</portType>
.....
<service name='FormClientDemographicsService'>
<port binding='ns1:FormClientDemographicsBinding'
name='FormClientDemographicsPort'>
<soap:address location=
'http://<machine>:<portnum>/formsWS/FormClientDemographicsBean'/>
</port>
</service>

 

Служебные параметры / возвращаемые значения лучше всего обрабатывать путем инкапсуляции их в отдельных объектах значений (в нашем случае FormClientDemographicsInput и FormClientDemographicsOutput соответственно). Поскольку классы будут использоваться JAXB для сериализации, они должны реализовывать интерфейс java.io.Serializable. По умолчанию JAXB сериализует все открытые поля и свойства, поэтому обычно нужно использовать @XmlAccessorType, чтобы выбрать только аннотированные поля для сериализации. @XmlType часто используется совместно для сопоставления типа класса или перечисления с типом схемы XML. Поэтому свойства и поля в этом классе будут отображаться в сложный тип с элементом propOrder, определяющим порядок последовательности элементов XML. Вам также необходимо указать целевое пространство имен схемы XML для пространства службы, используя пространство имен элемента аннотации.Вы можете определить как можно больше встроенных классов на любом уровне глубины, единственным условием является то, что все они реализуют интерфейс java.io.Serializable и должны быть украшены аннотацией @XmlType.

В листинге 6 показан объект значения Java, который передается в качестве параметра IN службе. В листинге 7 показано соответствующее определение схемы в сгенерированном документе WSDL.

Листинг 6 :

 

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(
name = "FormClientDemographicsInputType",
namespace="http://scrs.forms.service",
propOrder = { "contentURL", " inputSSN ", "formNum", " userAgent "}
)
public class FormClientDemographicsInput implements Serializable {
private ContentURL contentURL;
private String inputSSN;
private String formNum;
private String userAgent;

// Public getters and setters
}

 

Listing 7 :

<types>
<xs:schema targetNamespace='http://scrs.forms.service' version='1.0'
xmlns:tns='http://scrs.forms.service'
xmlns:xs='http://www.w3.org/2001/XMLSchema'>
<xs:element name='callRenderForm' nillable='true'
type='tns:FormClientDemographicsInputType'/>
<xs:complexType name='FormClientDemographicsInputType'>
<xs:sequence>
<xs:element minOccurs='0' name='contentURL' type='tns:contentURL'/>
<xs:element minOccurs='0' name='inputSSN' type='xs:string'/>
<xs:element minOccurs='0' name='formNum' type='xs:string'/>
<xs:element minOccurs='0' name='userAgent' type='xs:string'/>
</xs:sequence>
</xs:complexType>
<xs:complexType name='contentURL'>
<xs:sequence>
<xs:element minOccurs='0' name='scheme' type='xs:string'/>
<xs:element minOccurs='0' name='serverName' type='xs:string'/>
<xs:element minOccurs='0' name='serverPort' type='xs:string'/>
<xs:element minOccurs='0' name='contextPath' type='xs:string'/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</types>


Transmission Optimization

The MTOM (Message Transmission Optimization Mechanism) is a specification created by W3C [REF-4] to support selective encoding of portions of the message and provides a means of efficiently serializing XML infosets that have binary data content (eg. JPEG images, PDF files etc.). At the server (Endpoint) side binary optimization is enabled via the @BindingType annotation (refer to Listing 4). Web service clients generally enable MTOM at the Binding Provider (refer to Listing 11).

The Binary data (PDF) being returned is represented by an instance of javax.activation.DataHandler. The DataHandler class provides a consistent interface to data available in various different formats and can be constructed passing in a byte array. For example refer to Listing 8. The WSDL document generated for this source will contain the basic XML schema xs:base64Binary type which the runtime SOAP mechanism will encode it as.

Listing 8:

@XmlType(name="pdfContent",
namespace="http://scrs.forms.service",
propOrder = { "dataHandler" })
public class PDFContent {
private DataHandler dataHandler;

public PDFContent() {
}

public PDFContent(byte[] byteArrayPDF, String contentType) {
ByteArrayDataSource ds = new ByteArrayDataSource(byteArrayPDF, contentType);
DataHandler dh = new DataHandler(ds);
setDataHandler(dh);
}

// getter and setter
}

 
Handling Exceptions

The client should handle two types of exceptions both of which are translated into SOAP Fault messages by the binding framework: a runtime SOAPFaultException or an application level exception. The runtime exception will already have a fault bean generated for it by the framework. However, all unchecked exceptions thrown within the implementation bean or checked exceptions (eg. those that exist as part of the renderForm call), are handled via a generic application exception class which was aptly named FormException (refer to Listing 9).

This class consists of a constructor which takes in the error category, error code, short error message and a string represented array of the last 5 stack trace elements of the primary throwable cause which would likely make more sense for debugging purposes to the calling system or invoker of the WS. The FormException class was decorated with @WebFault used to annotate the service specific exception class (see Listing 10) to customize to the local and namespace name of the fault element and the name of the fault bean which eventually gets translated into the Fault message and accompanying schema mapping on the WSDL document.

Listing 9:

@WebFault(faultBean="forms.server.exception.FormExceptionBean")
public class FormException extends Exception
{
private int errorCode;
private String errorCategory;
private String[] stackTraceArr;

public FormException(String errorCategory, int errorCode, String message, String[] stackTraceArr)
{
super(message);
this.errorCategory = errorCategory;
this.errorCode = errorCode;
this.stackTraceArr = stackTraceArr;
}

// getters and setters
}

 

 

Listing 10:

@XmlRootElement(namespace = "http://scrs.forms.service/", name = "FormException")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(namespace = "http://scrs.forms.service/", name = "FormException", propOrder = {
"errorCategory",
"errorCode",
"message",
"stackTraceArr"
})
public class FormExceptionBean {
@XmlElement(namespace = "", name = "errorCategory")
private String errorCategory;
@XmlElement(namespace = "", name = "errorCode")
private int errorCode;
@XmlElement(namespace = "", name = "message")
private String message;
@XmlElement(namespace = "", name = "stackTraceArr")
private String[] stackTraceArr;

//getters and setters
}

 


Security

Security is very important for any service consumable within an enterprise environment. There are essentially 3 options for securing the service:

Transport level security using Secure Socket Layer technologies that secure the payload at the transport layer
Optionally, message level security using WS-Security that secures the payload at the SOAP message (application) level
Authentication and authorization of the client application credentials once the message arrives at its endpoint destination

Из-за деликатного характера передаваемых данных (информация о демографии клиентов, включая номера социального страхования и т. Д.) Технология SSL используется для того, чтобы предоставить всем клиентам, нуждающимся в доступе к службам форм, возможность безопасного обмена данными с зашифрованным сеансом. Указание атрибута transportGuarantee =
CONFIDENTIAL в аннотации @WebContext для конечной точки обеспечивает соблюдение требований безопасности транспорта для всех входящих / исходящих сообщений. Адрес конечной точки в документе WSDL также был изменен для использования защищенного протокола HTTPS, который по умолчанию использует порт 443, и соединителю с этим портом также было разрешено указывать на хранилище ключей, содержащее подписанный сертификат CA.

Внедренная модель безопасности состоит из базовой аутентификации / авторизации, при которой доступ к конечной точке SLSB защищается с помощью
аннотации
@SecurityDomain, в которой указывается область безопасности и
@RolesAllowed.аннотация (см. листинг 2), в которой указан список ролей, которым разрешен доступ к методам конечных точек. Область может хранить информацию об идентичности различными способами: файлы свойств, каталоги LDAP или базы данных, доступные через JDBC. Аутентификация во время выполнения включает в себя перехватчик безопасности, загружающий предварительно сконфигурированный LoginModule для аннотированной области конечной точки, которую он затем делегирует для проверки учетных данных вызывающего клиентского приложения. В JBoss самый простой способ — настроить контекст безопасности (область) в login-config.xml и использовать UserRolesLoginModule с файлами свойств, содержащими комбинации пользователя / пароля для аутентификации и пользователя / ролей для авторизации роли, разрешающей доступ к методам конечной точки ,

Клиенты веб-сервисов

Чтобы генерировать артефакты на стороне клиента с помощью JBossWS, обычно вы используете инструмент wsconsume для создания заглушек из документа WSDL. Обычно это дает набор файлов, один из которых называется классом реализации службы, который можно распознать, поскольку он будет иметь два открытых конструктора, один без аргументов и один с двумя аргументами, представляющими местоположение wsdl (a java.net.URL ) и полное имя службы wsdl (javax.xml.namespace.QName) соответственно. Сервлету, классу действия или любому другому компоненту на стороне клиента, который вызывает службу, потребуется получить экземпляр этого класса (созданный с помощью URL-адреса документа WSDL и определенного в нем QName службы), а затем вызвать метод getPort для возврата динамического прокси, который затем используется для вызова конечной точки целевой службы, как показано в листинге 11. Используйте javax.xml.ws.BindingProvider для установки комбинации имени пользователя и пароля для аутентификации в соответствии с безопасностью JBoss. Чтобы упростить переносимость между различными системами, которые должны использовать те же функциональные возможности на стороне клиента (как в нашем случае в PAC, EES и Member Access), вы обычно упаковываете сгенерированные клиентские артефакты (SEI, классы-оболочки для сообщений запроса и ответа, классы обслуживания) в отдельный архив Java (в нашем случае это называется FormsClient.jar) и просто включите файл jar в путь к классу вызывающего системного модуля.оберните классы для сообщений запроса и ответа, классов обслуживания) в отдельный архив Java (в нашем случае это называется FormsClient.jar) и просто включите файл jar в путь к классу вызывающего системного модуля.оберните классы для сообщений запроса и ответа, классов обслуживания) в отдельный архив Java (в нашем случае это называется FormsClient.jar) и просто включите файл jar в путь к классу вызывающего системного модуля.

Listing 11 :

public class FormGetAction extends Action {
private FormClientDemographics formClientDemographicsWS ;

public ActionForward execute(..) throws ServletException {
wsPortSetup();
try {
< resultObect> = seiWS. callRenderForm ();
} catch(FormException) {.. }
}

private void wsPortSetup()
{
QName serviceName = new QName("http://scrs.forms.service/", "FormClientDemographicsService");
URL wsdlURL = new URL();
Service service = Service.create(wsdlURL, serviceName);
formClientDemographicsWS = (FormClientDemographics)service.getPort(FormClientDemographics.class);

BindingProvider bp = (BindingProvider) seiWS;
SoapBinding binding = (SoapBinding) seiWS.getBinding();
binding.setMTOMEnabled(true);
bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "username");
bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "password");
}
}

 

Process View


Finally refer to Figure 2 and 3 for the view of the end-to-end architecture which diagrams the major objects (on the various intermediate systems), processes and related activity timelines involved in the system execution and their interactions.


Figure 2: Sequence Diagram — Rendering Adobe LiveCycle Forms



Figure 3: Sequence Diagram — Processing Form Submissions


Conclusion

Creating a JAX-WS service façade for automated Adobe LiveCycle forms components allows for the linking of forms to multiple processes across different external systems. The result is a leaner, efficient and better integrated process for accessing centralized forms functionality leading to increased data accuracy, reduced manual entry and substantive improvements in service delivery time for the agency. Using a high level framework like JBossWS obfuscates the complexity and details of converting between Java method invocations and the corresponding SOAP messages, replacing the need for a custom Java/XML data mapping and instead leveraging JAXB which allows mapping for any XML schema. Development and maintenance is greatly simplified with the use of annotations to define Web service endpoints, business methods, web context, security domain and service clients.

References

[REF-1] JBossWS User Documentation», JBoss.org, http://jbossws.jboss.org/mediawiki/index.php?title=JBossWS
[REF-2] «Lean Service Architectures with Java EE 6» by Adam Bien, JavaWorld.com, http://www.javaworld.com/javaworld/jw-04-2009/jw-04-lean-soa-with-javaee6.html
[REF-3] Java SOA Cookbook» by Eben Hewitt, O’Reilly Media Inc., http://oreilly.com/catalog/9780596520724/
[REF-4] «SOAP Message Transmission Optimization Mechanism», W3C Recommendation, http://www.w3.org/TR/soap12-mtom/

This article was originally published in The SOA Magazine (www.soamag.com), a publication officially associated with «The Prentice Hall Service-Oriented Computing Series from Thomas Erl» (www.soabooks.com). Copyright ©SOA Systems Inc. (www.soasystems.com)