2012-09-17 50 views
5

Java - JDK 1.6.0.7 - WSGEN -version: JAX-WS RI 2.2.3-b01-Java (servicio web - SOAP) - ¿Cómo agrego un controlador SOAP en el lado del cliente y habilito MTOM correcto?


Tengo el siguiente problema:

SOAPBinding binding = (SOAPBinding)((BindingProvider)port).getBinding(); 
binding.setMTOMEnabled(true); 

List<Handler> handlerChain = new ArrayList<Handler>(); 
handlerChain.addAll(binding.getHandlerChain()); 
handlerChain.add(new MyHandlerSecurity("admin", "admin")); 
binding.setHandlerChain(handlerChain); 

Con este código es correcto el SoapHeader , pero el archivo adjunto es siempre un texto base64 en línea.

//List<Handler> handlerChain = new ArrayList<Handler>(); 
//handlerChain.addAll(binding.getHandlerChain()); 
//handlerChain.add(new MyHandlerSecurity("admin", "admin")); 
//binding.setHandlerChain(handlerChain); 

Cuando HandlerChain está comentado, verá los datos adjuntos como una referencia xop, pero no hay SoapHeader y por lo tanto, el cliente no se autentica ...

¿Cómo puedo agregar un controlador de el lado del cliente y habilitar MTOM correcto?

Respuesta

6

No estoy seguro de si me dieron la pregunta correcta, pero creo que he tenido el mismo problema hace un par de meses, así que aquí está mi solución:

En primer lugar se necesita una clase HeaderHandler, cosa que crea el encabezado de jabón elemento, que debe tener este aspecto:


import javax.xml.namespace.QName; 
    import javax.xml.soap.SOAPElement; 
    import javax.xml.soap.SOAPEnvelope; 
    import javax.xml.soap.SOAPHeader; 
    import javax.xml.ws.handler.MessageContext; 
    import javax.xml.ws.handler.soap.SOAPHandler; 
    import javax.xml.ws.handler.soap.SOAPMessageContext; 


    public class HeaderHandler implements SOAPHandler<SOAPMessageContext> { 

     public boolean handleMessage(SOAPMessageContext smc) { 
      Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); 
      String AUTH_TK = "http://www.myurl.com:port/subdir/etc/"; 
      String NOPREFIX="";//no prefix 
      String PREFIX_XMLNS="xmlns"; 
      String value = "123456"; 
      if (outboundProperty.booleanValue()) { 
       try { 
        SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope(); 
        SOAPHeader header = envelope.addHeader(); 
        //<AuthorizationToken xmlns="http://www.myurl.com:port/subdir/etc/"> 
        SOAPElement authorizationToken = header.addChildElement("AuthorizationToken", PREFIX_XMLNS, AUTH_TK); 
        //<Token>value</Token> 
        SOAPElement usernameToken = 
         authorizationToken.addChildElement("Token", NOPREFIX); 
         usernameToken.addTextNode(value); 
         //<Token>value</Token> 
        SOAPElement usernameToken = 
         authorizationToken.addChildElement("Token", PREFIX); 
         usernameToken.addTextNode(value); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
      return outboundProperty; 
     } 


     public Set<QName> getHeaders() { 
      return null; 
     } 

     public void close(MessageContext arg0) { 

     } 

     public boolean handleFault(SOAPMessageContext arg0) { 
      return false; 
     } 
    } 

Después de que se crea un HeaderHandlerResolver para manejar la creación de cabecera y la inserta en una cadena manejador:


import java.util.ArrayList; 
    import java.util.List; 
    import javax.xml.ws.handler.Handler; 
    import javax.xml.ws.handler.HandlerResolver; 
    import javax.xml.ws.handler.PortInfo; 

    public class HeaderHandlerResolver implements HandlerResolver { 

    @SuppressWarnings("unchecked") 
    public List<Handler> getHandlerChain(PortInfo portInfo) { 
      List<Handler> handlerChain = new ArrayList<Handler>(); 
      HeaderHandler hh = new HeaderHandler(); 
      handlerChain.add(hh); 
      return handlerChain; 
     } 
    } 

Después de eso, se agrega en el cliente:


 try{ 
      //new service instance (your service should be extending javax.xml.ws.Service;) 
      YourServiceProxy service = new YourServiceProxy(); 
      //calls the header handler resolver ;) 
      service.setHandlerResolver(new HeaderHandlerResolver()); 
      //get the service 
      YourService port = (YourService)service.getYourService(); 
      //call the service 
      port.yourMethod() 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

Por cierto, no he probado esta cabecera en particular, he modificado un controlador de cabecera anterior que tenía, por lo que puede no ser exacto, pero creo que es bastante cercano, realmente espero que te sirva de ayuda, pruébalo y cuéntanos cómo se produce, intentaré ayudarte si aún no funciona.

+1

Esta respuesta fue usefult para mí cuando necesité configurar un loggingHandler (algo que registra las solicitudes/respuestas) en un cliente ws. Gracias. – riskop

+0

¿Cuál es el resultado de devolver falso desde el método handleFault? ¿Y qué hay de devolver null desde el método getHeaders? –

+0

@NicholasDiPiazza devolver falso bloqueará el procesamiento del mensaje, básicamente está diciendo "si este controlador falla descarta todo el mensaje", compruebe https://docs.oracle.com/javaee/5/api/javax/xml/ws/handler/ Handler.html # handleFault (C) Al devolver null en getHeaders, usted es "este manejador no maneja un encabezado específico", por lo que tenemos nuestro propio manejador de resolución, retrospectivamente, es probable que pueda deshacerse del manejador de resolver devolviendo el encabezados a la derecha pero no lo he intentado https://docs.oracle.com/javaee/5/api/javax/xml/ws/handler/soap/SOAPHandler.html#getHeaders() –

Cuestiones relacionadas