Te llega un mensaje SOAP, y lo tienes que modificar porque hay una coma que esta en mal sitio. Vamos a usar Interceptors para ello.
Este es el mensaje que me llega y que quiero modificar:
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<soapenv:Fault>
<faultcode>env:Server</faultcode>
<faultstring>0301 - Organismo no autorizado 'XXXXXXXX' 'CDISFWS01'</faultstring>
<faultactor>CDISFWS01</faultactor>
<detail>
<Atributos xmlns="http://www.map.es/scsp/esquemas/V2/soapfaultatributos">
<IdPeticion>1390410889105</IdPeticion>
<NumElementos>1</NumElementos>
<TimeStamp>2014-01-22T18:14:20.651+01:00</TimeStamp>
<Estado>
<CodigoEstado>0301</CodigoEstado>
<CodigoEstadoSecundario />
<LiteralError>Organismo no autorizado 'XXXXXXXX' 'CDISFWS01'</LiteralError>
<TiempoEstimadoRespuesta>0</TiempoEstimadoRespuesta>
</Estado>
<CodigoCertificado>CDISFWS01</CodigoCertificado>
</Atributos>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
Lo que esta mal:
env:Server
Como debiera esta bien:
soapenv:Server
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server</faultcode>
<faultstring>0301 - Organismo no autorizado 'XXXXXXXX' 'CDISFWS01'</faultstring>
<faultactor>CDISFWS01</faultactor>
<detail>
<Atributos xmlns="http://www.map.es/scsp/esquemas/V2/soapfaultatributos">
<IdPeticion>1390410889105</IdPeticion>
<NumElementos>1</NumElementos>
<TimeStamp>2014-01-22T18:14:20.651+01:00</TimeStamp>
<Estado>
<CodigoEstado>0301</CodigoEstado>
<CodigoEstadoSecundario />
<LiteralError>Organismo no autorizado 'XXXXXXXX' 'CDISFWS01'</LiteralError>
<TiempoEstimadoRespuesta>0</TiempoEstimadoRespuesta>
</Estado>
<CodigoCertificado>CDISFWS01</CodigoCertificado>
</Atributos>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
Utilizo esta clase que algun compañero de profesion dejo en stackoverflow.com. Yo simplemente he modificado el uso del log.
package una.ruta.a.un.paquete;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.slf4j.LoggerFactory;
public abstract class MessageChangeInterceptor extends AbstractPhaseInterceptor<Message> {
private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(MessageChangeInterceptor.class);
public MessageChangeInterceptor() {
super(Phase.PRE_STREAM);
addBefore(SoapPreProtocolOutInterceptor.class.getName());
}
protected abstract String changeOutboundMessage(String currentEnvelope);
protected abstract String changeInboundMessage(String currentEnvelope);
public void handleMessage(Message message) {
boolean isOutbound = false;
isOutbound = message == message.getExchange().getOutMessage()
|| message == message.getExchange().getOutFaultMessage();
if (isOutbound) {
OutputStream os = message.getContent(OutputStream.class);
CachedStream cs = new CachedStream();
message.setContent(OutputStream.class, cs);
message.getInterceptorChain().doIntercept(message);
try {
cs.flush();
IOUtils.closeQuietly(cs);
CachedOutputStream csnew = (CachedOutputStream) message.getContent(OutputStream.class);
String currentEnvelopeMessage = IOUtils.toString(csnew.getInputStream(), "UTF-8");
csnew.flush();
IOUtils.closeQuietly(csnew);
LOGGER.debug("Outbound message: " + currentEnvelopeMessage);
String res = changeOutboundMessage(currentEnvelopeMessage);
if (res != null) {
LOGGER.debug("Outbound message has been changed: " + res);
}
res = res != null ? res : currentEnvelopeMessage;
InputStream replaceInStream = IOUtils.toInputStream(res, "UTF-8");
IOUtils.copy(replaceInStream, os);
replaceInStream.close();
IOUtils.closeQuietly(replaceInStream);
os.flush();
message.setContent(OutputStream.class, os);
IOUtils.closeQuietly(os);
} catch (IOException ioe) {
LOGGER.warn("Unable to perform change.", ioe);
throw new RuntimeException(ioe);
}
} else {
try {
InputStream is = message.getContent(InputStream.class);
String currentEnvelopeMessage = IOUtils.toString(is, "UTF-8");
IOUtils.closeQuietly(is);
LOGGER.debug("Inbound message: " + currentEnvelopeMessage);
String res = changeInboundMessage(currentEnvelopeMessage);
if (res != null) {
LOGGER.debug("Inbound message has been changed: " + res);
}
res = res != null ? res : currentEnvelopeMessage;
is = IOUtils.toInputStream(res, "UTF-8");
message.setContent(InputStream.class, is);
IOUtils.closeQuietly(is);
} catch (IOException ioe) {
LOGGER.warn("Unable to perform change.", ioe);
throw new RuntimeException(ioe);
}
}
}
public void handleFault(Message message) {
}
private class CachedStream extends CachedOutputStream {
public CachedStream() {
super();
}
protected void doFlush() throws IOException {
currentStream.flush();
}
protected void doClose() throws IOException {
}
protected void onWrite() throws IOException {
}
}
}
Y la clase que hereda de la anterior, y realiza el cambio requerido:
package una.ruta.a.un.paquete;
import org.slf4j.LoggerFactory;
public class InterceptorInSoapFaultBug extends MessageChangeInterceptor {
private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(InterceptorInSoapFaultBug.class);
@Override
protected String changeOutboundMessage(String currentEnvelope) {
// TODO Auto-generated method stub
return null;
}
@Override
protected String changeInboundMessage(String currentEnvelope) {
if((currentEnvelope != null) && (currentEnvelope.contains(">env:Server<"))){
LOGGER.info("Debido a un bug en el mensaje SoapFault de este servicio. se procede a cambiar la etiqueta "env:Server" por "soapenv:Server".");
currentEnvelope = currentEnvelope.replace(">env:Server<", ">soapenv:Server<");
}
return currentEnvelope;
}
}
Posteriormente en el fichero de configuracion de Spring tendrias que invocarlo:
<!-- ... -->
<bean id="bugSoapFault" class="una.ruta.a.un.paquete.InterceptorInSoapFaultBug" />
<!-- ... -->
<jaxws:client id="clientPaxaseConsultaIdentidad" address="#{url}"
serviceClass="es.map.xml_schemas.PeticionPortType">
<!-- <jaxws:properties> -->
<!-- <entry key="schema-validation-enabled" value="true" /> -->
<!-- </jaxws:properties> -->
<jaxws:inFaultInterceptors>
<ref bean="logInbound" />
<ref bean="bugSoapFault" />
</jaxws:inFaultInterceptors>
<jaxws:inInterceptors>
<!-- cierra todas las etiquetas y rellena lo que falta -->