web-services - paso - web service java netbeans
JAXWS: problemas que generan la estructura correcta del mensaje SOAP (2)
Tenemos una aplicación que necesita consumir un servicio web externo. Para hacer esto, hemos generado el conjunto de artefactos Java del WSDL a través de Maven utilizando el objetivo wsdl2java proporcionado por el complemento cxf-codegen-plugin.
Hemos escrito una prueba de integración como parte de nuestro conjunto de pruebas que llama al servicio web real y todo funciona bien.
El código para integrar con el servicio web real se empaqueta luego en un conjunto de JAR y se utiliza dentro de la aplicación de front-end que necesita usar el servicio web.
Estamos teniendo un problema cuando la aplicación FE usa el código de integración. Exactamente el mismo código está siendo ejecutado por la aplicación FE como se está utilizando en nuestra prueba de integración de trabajo, pero el mensaje SOAP que finalmente se genera es diferente entre los dos y el mensaje generado por la aplicación real es incorrecto.
La solicitud SOAP de trabajo producida por nuestras pruebas de integración es:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns12:ProcessUIRequest xmlns:ns10="http://zzz/yyyentityview/validation/"
xmlns:ns11="http://zzz/yyyview/search/list/"
xmlns:ns12="http://zzz/yyywebservice/v5/types/"
xmlns:ns2="http://zzz/yyyentityview/app/"
xmlns:ns3="http://zzz/yyyentityview/client/"
xmlns:ns4="http://zzz/yyyview/search/postcode/"
xmlns:ns5="http://zzz/yyyview/app/"
xmlns:ns6="http://zzz/yyyview/search/app/"
xmlns:ns7="http://zzz/yyyview/search/bank/"
xmlns:ns8="http://zzz/yyyview/uw/"
xmlns:ns9="http://zzz/yyybase/">
<ns12:ProcessUIRequest CallType="Submit" DisplayError="false"
IsAnonymous="false" IsCompactRequest="false" IsError="false">
<ns9:ModelData>
<ns9:TransactionData ApplicationReference="20000003CR3.00000003"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="ns5:QuoteLoadTxnDataVO" />
</ns9:ModelData>
<ns9:Activity ActionCode="QuoteLoad" ActionMode="Default"
ActivityCode="QuoteApplicationFull" ActivityMode="Default"
ActivityReference="" ActivityStatus="Inital"
ActivityTransaction="StartNewActivityAndLogOffUser"
CanProceedWithValidationsOutstanding="true">
<ns9:BusinessKeys>
<item>
<key>
<string>ADVREF</string>
</key>
<value>
<BusinessKeyVO KeyName="ADVREF" KeyValue="AVAGT01">
<BusinessKey KeyName="ADVREF" KeyType="Unknown"
KeyValue="AVAGT01" />
</BusinessKeyVO>
</value>
</item>
</ns9:BusinessKeys>
</ns9:Activity>
</ns12:ProcessUIRequest>
</ns12:ProcessUIRequest>
</S:Body>
</S:Envelope>
El POJO que se organiza en esa solicitud SOAP es:
<tcp.ssgbase.BaseVO>
<modelData>
<transactionData class="tcp.ssgview.app.QuoteLoadTxnDataVO">
<applicationReference>20000003CR3.00000003</applicationReference>
</transactionData>
</modelData>
<activity>
<businessKeys>
<item>
<tcp.serializable__dictionary.BusinessKeyItem>
<key>
<string>ADVREF</string>
</key>
<value>
<businessKeyVO>
<businessKey>
<keyName>ADVREF</keyName>
<keyValue>AVAGT01</keyValue>
<keyType>Unknown</keyType>
</businessKey>
<keyName>ADVREF</keyName>
<keyValue>AVAGT01</keyValue>
</businessKeyVO>
</value>
</tcp.serializable__dictionary.BusinessKeyItem>
</item>
</businessKeys>
<actionMode>DEFAULT</actionMode>
<activityMode>DEFAULT</activityMode>
<activityTransaction>START_NEW_ACTIVITY_AND_LOG_OFF_USER</activityTransaction>
<actionCode>QuoteLoad</actionCode>
<activityReference></activityReference>
<activityStatus>INITAL</activityStatus>
<activityCode>QuoteApplicationFull</activityCode>
<canProceedWithValidationsOutstanding>true</canProceedWithValidationsOutstanding>
</activity>
<displayError>false</displayError>
<isAnonymous>false</isAnonymous>
<isError>false</isError>
<isCompactRequest>false</isCompactRequest>
<callType>SUBMIT</callType>
</tcp.ssgbase.BaseVO>
La solicitud SOAP generada por la aplicación FE real es:
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Body>
<ns2:ProcessUIRequest xmlns:ns2="http://zzz/yyywebservice/v5/types/">
<processUIRequest>
<activity>
<actionCode>QuoteLoad</actionCode>
<actionMode>DEFAULT</actionMode>
<activityCode>QuoteApplicationFull</activityCode>
<activityMode>DEFAULT</activityMode>
<activityReference />
<activityStatus>INITAL</activityStatus>
<activityTransaction>
START_NEW_ACTIVITY_AND_LOG_OFF_USER</activityTransaction>
<businessKeys />
<canProceedWithValidationsOutstanding>
true</canProceedWithValidationsOutstanding>
</activity>
<callType>SUBMIT</callType>
<displayError>false</displayError>
<isAnonymous>false</isAnonymous>
<isCompactRequest>false</isCompactRequest>
<isError>false</isError>
<modelData>
<transactionData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="ns2:quoteLoadTxnDataVO">
<applicationReference>
20000003ESF.00000018</applicationReference>
</transactionData>
</modelData>
</processUIRequest>
</ns2:ProcessUIRequest>
</soapenv:Body>
</soapenv:Envelope>
El POJO que se organiza en esa solicitud SOAP es:
<tcp.ssgbase.BaseVO>
<modelData>
<transactionData class="tcp.ssgview.app.QuoteLoadTxnDataVO">
<applicationReference>20000003ESF.00000018</applicationReference>
</transactionData>
</modelData>
<activity>
<businessKeys>
<item>
<tcp.serializable__dictionary.BusinessKeyItem>
<key>
<string>ADVREF</string>
</key>
<value>
<businessKeyVO>
<businessKey>
<keyName>ADVREF</keyName>
<keyValue>AVAGT01</keyValue>
<keyType>Unknown</keyType>
</businessKey>
<keyName>ADVREF</keyName>
<keyValue>AVAGT01</keyValue>
</businessKeyVO>
</value>
</tcp.serializable__dictionary.BusinessKeyItem>
</item>
</businessKeys>
<actionMode>DEFAULT</actionMode>
<activityMode>DEFAULT</activityMode>
<activityTransaction>START_NEW_ACTIVITY_AND_LOG_OFF_USER</activityTransaction>
<actionCode>QuoteLoad</actionCode>
<activityReference></activityReference>
<activityStatus>INITAL</activityStatus>
<activityCode>QuoteApplicationFull</activityCode>
<canProceedWithValidationsOutstanding>true</canProceedWithValidationsOutstanding>
</activity>
<displayError>false</displayError>
<isAnonymous>false</isAnonymous>
<isError>false</isError>
<isCompactRequest>false</isCompactRequest>
<callType>SUBMIT</callType>
</tcp.ssgbase.BaseVO>
Puede ver que la estructura de las dos solicitudes es diferente a pesar de que el código que se ejecuta en nuestros JAR de integración es exactamente el mismo y la estructura de los POJO utilizados para crear el mensaje SOAP es la misma (salvo un valor). A partir de la solicitud, parece que la solicitud generada en la aplicación FE no recoge el WSDL correcto y los XSD asociados.
Nuestro código para generar la implementación correcta de la interfaz de punto final del servicio es:
private <T> T createServiceObject(final Class<T> p_seiClass) throws ApplicationException {
try {
final Service serviceFactory = Service.create(new URL(wsdlLocation), new QName(targetNamespace, serviceName));
final SoapHandlerResolver handlerResolver = new SoapHandlerResolver();
handlerResolver.addHandler(new SoapMessageLoggingHandler());
serviceFactory.setHandlerResolver(handlerResolver);
final T service = serviceFactory.getPort(p_seiClass);
((BindingProvider) service).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"endpoint");
return service;
} catch (MalformedURLException e) {
throw new ApplicationException(ApplicationErrorCode.COMM_ERR_UNEXPECTED_ERROR, e);
}
}
Después de hacer algunas depuraciones, he notado que la instancia de serviceFactory es diferente en la prueba de integración y cuando estamos ejecutando dentro de la aplicación FE.
En la prueba de integración, la instancia de la clase (tomada del depurador Eclipse donde ejecutamos la prueba de integración usando jUnit) es: ''JAX-WS RI 2.1.6 en JDK 6: Stub for'' y parece ser del tipo '' SEIStub ''.
Cuando se ejecuta dentro de la aplicación FE, la instancia de la clase es org.apache.axis2.jaxws.client.proxy.JAXWSProxyHandler. La aplicación FE se aloja y ejecuta en WebSphere Application Server.
Entonces, mi pregunta es: ¿qué podría estar sucediendo cuando se ejecuta en la aplicación FE real para hacer que las definiciones incorrectas de WSDL y XSD se recojan al coordinar el POJO en la solicitud SOAP? He pasado mucho tiempo tratando de depurar esto, pero fue en vano.
Tuve esta experiencia cuando intentaba escribir una aplicación cliente y desplegarla en Web Logic Server. Debe usar la versión exacta de java que utiliza el servidor al crear las clases. La solicitud de jabón se crea internamente por JVM. Si JVM es diferente mientras crea las clases y las prueba y mientras las consume en tiempo real, SOAP será o puede ser diferente.
Las dos solicitudes de jabón son diferentes porque, como ya dijiste , las dos serviceFactory
son diferentes y usan diferentes especificaciones 1.1
y 1.2
.
Mi sugerencia es que configure su proyecto de maven para importar las jarras correctas en su entorno de prueba o actualice el jar en el contenedor (el jar que crea el serviceFactory
). Como no estoy familiarizado con cxf-codegen-plugin, no puedo sugerir más que eso.
Esta sugerencia fue publicada originalmente como un comentario. El OP pide ponerlo como una respuesta.