Pregunta

He creado una extensión de GenericHandler llamada SOAPHeaderHandler. Coloqué las declaraciones log4j en el controlador y puedo ver el constructor que se está construyendo. Sin embargo, cuando genero un mensaje SOAP, no veo el mensaje relacionado con el método handleRequest. He registrado el controlador en el código auxiliar de la siguiente manera:

if (service == null) {
    super.service = new com.ibm.ws.webservices.engine.client.Service();
}
else {
    super.service = service;
}
List handlerInfoList = new ArrayList();
QName[] headersArr = null;
HandlerInfo handlerInfo = new HandlerInfo(com.xxxxxx.hdhp.business.debitcard.cardservices.CardServiceSOAPHeaderHandler.class, 
     null, headersArr);
handlerInfoList.add(handlerInfo);
service.getHandlerRegistry().setHandlerChain(new QName("MetavanteDebitCard"), handlerInfoList);

El controlador es:

public class AccountManagementSOAPHeaderHandler extends GenericHandler {
 private static Logger logger = Logger.getLogger  (AccountManagementSOAPHeaderHandler.class);
 private HandlerInfo handlerInfo = null;

public AccountManagementSOAPHeaderHandler () {
 logger.info("Constructing AccountManagementSOAPHeaderHandler");
}

 /* (non-Javadoc)
  * @see javax.xml.rpc.handler.GenericHandler#getHeaders()
  */
 public QName[] getHeaders() {
 logger.info("calling getHeaders()");
  return null;
 }

 public boolean handleFault(MessageContext arg0) {
     logger.info("Fault in AccountManagementSOAPHeaderHandler");
  return true;
 }
 public boolean handleResponse(MessageContext arg0) {
   logger.info("Response in AccountManagementSOAPHeaderHandler");
   return true;
 }
 public void init(HandlerInfo arg0) {
  logger.info("init in AccountManagementSOAPHeaderHandler");
  handlerInfo = arg0;
  super.init(arg0);
 }

 public void destroy() {
  logger.info("--- In AccountManagementSOAPHeaderHandler.destroy ()");
 } 

 public boolean handleRequest(MessageContext ctx) {
     logger.debug("BEGIN handleRequest()");
     if (ctx instanceof SOAPMessageContext) {
        SOAPMessageContext context = (SOAPMessageContext) ctx;
        logger.debug("instance of SOAPMessageContext");
        try {
           SOAPHeader header = context.getMessage().getSOAPPart()
                .getEnvelope().getHeader();
           logger.debug("SOAP Header is " + ((header==null)?"NULL":"NOT NULL"));
           Iterator headers = header
                .extractHeaderElements("http://schemas.xmlsoap.org/soap/actor/next");
           while (headers.hasNext()) {
               SOAPHeaderElement he = (SOAPHeaderElement) headers.next();
               logger.info("HEADER Qn " + he.getElementName().getQualifiedName());
           }
       } catch (SOAPException x) {
           logger.error("SOAPException while handlingRequest for SOAP: '" + x.getMessage() + "'");
   }
  }
 return true;
}

y he cambiado el web.xml de la siguiente manera:

   <service-ref>
        <description>WSDL Service AccountManagerService</description>
        <service-ref-name>service/AccountManagerService</service-ref-name>
        <service-interface>com.medibank.www.AccountManagerService</service-interface>
<!--        <wsdl-file>WEB-INF/wsdl/AccountManagerService.asmx.wsdl</wsdl-file>-->
        <jaxrpc-mapping-file>WEB-INF/AccountManagerService.asmx_mapping.xml</jaxrpc-mapping-file>
        <service-qname xmlns:pfx="http://www.medibank.com/MBIWebServices/Access/Services/AccountManager/2004/06/">pfx:AccountManagerService</service-qname>
        <port-component-ref>
            <service-endpoint-interface>com.medibank.www.AccountManagerServiceSoap</service-endpoint-interface>
        </port-component-ref>
        <port-component-ref>
            <service-endpoint-interface>com.medibank.www.AccountManagerServiceSoap</service-endpoint-interface>
        </port-component-ref>
        <handler>
         <description>
         </description>
         <display-name></display-name>
         <handler-name>AccountManagementSOAPHeaderHandler</handler-name>
         <handler-class>com.xxxxx.hdhp.business.debitcard.accountmanagement.AccountManagementSOAPHeaderHandler</handler-class>
        </handler>
    </service-ref>

Esto se implementa en Websphere Application Server v6.0.2.35. ¿Alguna idea de cuál puede ser el problema? ¿Por qué las declaraciones del registrador en el controlador nunca se ejecutan? ¿No he podido registrar el controlador correctamente? ¿Debo especificar qué métodos de servicio se manejan?

¿Fue útil?

Solución

Escribí algunos clientes SOAP JAX-RPC que se ejecutan en WAS 6.0, y requieren GenericHandlers que agreguen un encabezado SOAP personalizado para solicitar mensajes. También tenía el requisito de no usar una referencia de servicio (por razones de facilidad de uso en la base de código del cliente), por lo que mi clase de cliente configura el controlador de manera programática. Esto puede no aplicarse exactamente a cómo funciona su configuración, pero tal vez algo sea útil.

Comencé con el código de cliente generado por la herramienta WSDL2Java de RAD 7.5 en Ant, pero el "Cliente de servicio web" El asistente también lo usa. Creó todos los objetos de negocio, serializador / deserializadores, localizador y clases de enlace SOAP, etc., etc. Luego creé un GenericHandler personalizado similar al que tiene.

Como no tenía una referencia de servicio disponible, no podía vincularla al cliente de esa manera. Así que usé el siguiente código en la clase del cliente en sí, para agregar programáticamente el controlador:

private AccountManager createAccountManagerStub() throws Exception {
    AccountManagerServiceLocator locator = new AccountManagerServiceLocator();

    // Set the JMS endpoint address
    AccountManagerSOAPBindingStub accountManagerStub = (AccountManagerSOAPBindingStub) locator
            .getAccountManagerSOAPPort(new URL(generateJMSEndpointAddress()));

    // Set the Client Handler
    HandlerRegistry registry = locator.getHandlerRegistry();
    List chain = registry
            .getHandlerChain((QName) locator.getPorts().next());
    HandlerInfo handlerInfo = new HandlerInfo();
    handlerInfo.setHandlerClass(AccountManagerClientHandler.class);
    chain.add(handlerInfo);

    return (AccountManager) accountManagerStub;
}

El objeto devuelto por ese método está completamente configurado y llamar a cualquiera de los métodos del cliente en esa clase funciona correctamente. Se invoca el método AccountManagerClientHandler.handleRequest (MessageContext msgContext), se actualiza el mensajeContext y luego el mensaje se envía de manera alegre.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top