Domanda

Ho creato un'estensione di GenericHandler chiamata SOAPHeaderHandler. Ho inserito le istruzioni log4j nel gestore e posso vedere il costruttore in costruzione. Quando genera un messaggio SOAP, tuttavia, non vedo il messaggio relativo al metodo handleRequest. Ho registrato l'handler nello stub come segue:

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);

Il gestore è:

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;
}

e ho modificato web.xml come segue:

   <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>

Questo è distribuito su Websphere Application Server v6.0.2.35. Qualche idea su quale possa essere il problema? Perché le istruzioni del logger nel gestore non vengono mai eseguite? Non sono riuscito a registrare correttamente il gestore? Devo specificare quali metodi di servizio vengono gestiti?

È stato utile?

Soluzione

Ho scritto alcuni client SOAP JAX-RPC eseguiti su WAS 6.0 e richiedono GenericHandlers che aggiungono un'intestazione SOAP personalizzata per richiedere i messaggi. Avevo anche il requisito di non utilizzare un service-ref (per motivi di facilità d'uso nella base di codice client), quindi la mia classe client imposta il gestore in modo programmatico. Questo potrebbe non essere esattamente applicabile a come funziona la tua configurazione, ma forse qualcosa sarà utile.

Ho iniziato con il codice client generato dallo strumento WSDL2Java di RAD 7.5 in Ant, ma il "client del servizio Web" lo usa anche il mago. Ha creato tutti gli oggetti business, serializzatori / deserializzatori, localizzatori e classi di associazione SOAP, ecc. Ecc. Ho quindi creato un GenericHandler personalizzato simile a quello che hai.

Dato che non avevo a disposizione un servizio-ref, non potevo collegarlo al client in quel modo. Quindi ho usato il seguente codice nella stessa classe client, per aggiungere a livello di codice il gestore:

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;
}

L'oggetto restituito da quel metodo è completamente impostato e la chiamata a uno qualsiasi dei metodi client su quella classe funziona correttamente. Viene invocato il metodo AccountManagerClientHandler.handleRequest (MessageContext msgContext), aggiornato messageContext e quindi inviato il messaggio nel modo giusto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top