我有以下SOAPHandler
package fi.***.ws;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Set;
import javax.ejb.EJB;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import ***
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class MyLoggingHandler implements SOAPHandler<SOAPMessageContext> {
@EJB private AsetusDAO asetusDAO;
@EJB private SanomalokiDAO sanomalokiDAO;
public void tallennaLokirivi(Suunta suunta, String palvelu, String sanoma) {
Sanomaloki loki = new Sanomaloki();
loki.setSuunta(new BigDecimal(suunta.getValue()));
loki.setPalvelu(palvelu);
loki.setSanoma(sanoma);
sanomalokiDAO.tallennaLokirivi(loki);
}
public String getPalvelu(SOAPMessageContext ctx) {
SOAPEnvelope msg;
SOAPBody body;
String operationName;
try {
msg = ctx.getMessage().getSOAPPart().getEnvelope();
body = msg.getBody();
operationName = body.getChildNodes().item(1).getLocalName();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return operationName;
}
public String getSanomaXML(SOAPMessageContext ctx) {
SOAPMessage message;
String sanomaXML;
final StringWriter sw = new StringWriter();
try {
message = ctx.getMessage();
TransformerFactory.newInstance().newTransformer().transform(
new DOMSource(message.getSOAPPart()),
new StreamResult(sw));
sanomaXML = sw.toString();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return sanomaXML;
}
public boolean isSanomalokiPaalla() {
Asetus lokitus = asetusDAO.haeAsetus(AsetusDAO.Avain.A1_SANOMALOKI_PAALLA);
return DatabaseConstants.A1_SANOMALOKI_PAALLA_1_VALUE.equals(lokitus.getArvo());
}
@Override
public boolean handleMessage(SOAPMessageContext context) {
if (!isSanomalokiPaalla())
return true;
String palvelu = getPalvelu(context);
String sanoma = getSanomaXML(context);
boolean isRequest = !((Boolean) context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue();
if (isRequest) {
// request
System.out.println("--- Logging handler message request ---");
tallennaLokirivi(Suunta.SISAAN, palvelu, sanoma);
} else {
// response
System.out.println("--- Logging handler message response ---");
tallennaLokirivi(Suunta.ULOS, palvelu, sanoma);
}
return true; // return false;
}
@Override
public boolean handleFault(SOAPMessageContext context) {
if (!isSanomalokiPaalla())
return true;
System.out.println("--- Logging handler message fault ---");
String palvelu = getPalvelu(context);
String sanoma = getSanomaXML(context);
tallennaLokirivi(Suunta.ULOS, palvelu, sanoma);
return true; // return false;
}
@Override
public void close(MessageContext context) {
System.out.println("--- close ---");
}
@Override
public Set<QName> getHeaders() {
System.out.println("--- getHeaders---");
return Collections.emptySet();
}
}
调用Web服务会返回以下错误
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns0:Fault xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.w3.org/2003/05/soap-envelope">
<faultcode>ns0:Server</faultcode>
<faultstring>Exception Description: The object [?], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[x-->x/text()]] with descriptor [XMLDescriptor(fi.***.PisteTyyppi --> [])], could not be converted to [class java.lang.Integer].
Internal Exception: java.lang.NumberFormatException: For input string: "?"</faultstring>
</ns0:Fault>
</S:Body>
</S:Envelope>
是导致此错误的getPalvelu
和getSanomaXML
方法。但是,由于某些原因 catch子句未捕获到异常。 handleMessage
方法实际上是在没有调用handleFault
方法的情况下完成的。另外,如果我从处理程序中删除这些方法,Web服务实现将友好地绑定参数,并且不会引发任何错误。
显然,Java SOAP API在内部捕获异常并设置故障。为什么我在处理程序上遇到此错误,并且有什么方法可以捕获异常?
答案 0 :(得分:0)
根据jax-ws 2.2 specification的9.3.2.1节,当您抛出一个非ProtocolException(或其子类)时,这是预期的行为,因此,如果您想通过handleFault方法处理那些异常您必须重新抛出ProtocolException而不是RuntimeException。另外,该handleFault方法必须位于单独的SOAPHandler中,因为消息交换模式将跳过当前句柄的handleFault并将错误传递给前一个。
Here,您可以看到不同情况下消息流的一些不错的框图。