Hola a todos, hace algún tiempo necesite capturar un mensaje SOAP desde el código y poder conocer desde su cabecera hasta su contenido para poderlo manipular, al revisar información para implementarlo en CXF con Spring realice lo siguiente:
1.) Crear un clase Java
import javax.xml.namespace.QName;
import javax.xml.soap.*;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import javax.xml.ws.soap.SOAPFaultException;
import java.util.Set;
/**
*
*/
public class HandlerChain implements SOAPHandler<SOAPMessageContext> {
public boolean handleMessage(SOAPMessageContext context) {
System.out.println("Server : handleMessage()......");
Boolean isRequest = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
//for response message only, true for outbound messages, false for inbound
if(!isRequest){
try{
SOAPMessage soapMsg = context.getMessage();
SOAPEnvelope soapEnv = soapMsg.getSOAPPart().getEnvelope();
SOAPHeader soapHeader = soapEnv.getHeader();
System.out.println("Msg " + soapMsg.getSOAPHeader());
//if no header, add one
if (soapHeader == null){
soapHeader = soapEnv.addHeader();
//throw exception
generateSOAPErrMessage(soapMsg, "No SOAP header.");
}
}catch(SOAPException e){
System.err.println(e);
}
}
return true;
}
public boolean handleFault(SOAPMessageContext context) {
System.out.println("Server : handleFault()......");
return true;
}
public void close(MessageContext context) {
System.out.println("Server : close()......");
}
public Set<QName> getHeaders() {
System.out.println("Server : getHeaders()......");
return null;
}
private void generateSOAPErrMessage(SOAPMessage msg, String reason) {
try {
SOAPBody soapBody = msg.getSOAPPart().getEnvelope().getBody();
SOAPFault soapFault = soapBody.addFault();
soapFault.setFaultString(reason);
throw new SOAPFaultException(soapFault);
}
catch(SOAPException e) { }
}
}
2.) Crear un XML con lo siguiente (El "class_path" se debe reemplazar por la ruta donde se haya creado la clase del punto uno):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<javaee:handler-chains
xmlns:javaee="http://java.sun.com/xml/ns/javaee"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<javaee:handler-chain>
<javaee:handler>
<javaee:handler-class>class_path.HandlerChain</javaee:handler-class>
</javaee:handler>
</javaee:handler-chain>
</javaee:handler-chains>
3.) En la implementación del WS se coloca lo siguiente:
@HandlerChain(file="/handler-chain.xml")
////Agregar Header SOAP
List<Header> headers = new ArrayList<Header>();
Header dummyHeader = new Header(new QName("uri:org.apache.cxf", "dummy"), "decapitated",
new JAXBDataBinding(String.class));
headers.add(dummyHeader);
//server side:
context.getMessageContext().put(Header.HEADER_LIST, headers);
//client side:
((BindingProvider)proxy).getRequestContext().put(Header.HEADER_LIST, headers);
Esto en gran parte fue tomado del siguiente link:
Espero que esta información les ayude, y hasta una futura oportunidad.
Comentarios
Publicar un comentario