如何从SOAPConnection.call()
答案 0 :(得分:9)
取自W3C note on SOAP (Section 6.2)
SOAP HTTP遵循HTTP状态代码的语义 在HTTP中传递状态信息。例如,2xx状态 代码表示客户端的请求包括SOAP组件 成功接收,理解和接受等。
如果在处理请求时出现SOAP错误,则为SOAP HTTP 服务器必须发出HTTP 500“内部服务器错误”响应和 在包含SOAP Fault元素的响应中包含SOAP消息 (参见第4.4节)表明SOAP处理错误。
来自documentation on SOAPFault in the API
SOAPBody对象中包含错误和/或状态的元素 信息即可。此信息可能与SOAPMessage中的错误有关 对象或与内容无关的问题 消息本身。
所以,可能的答案可能是
SoapMessage soapMessage = null;
soapMessage = MySOAPConnection.call(...);
soapMessage.getSOAPPart().getEnvelope().getBody().getFault().getFaultCode();
一些帮助我创建这个答案的参考文献是:
答案 1 :(得分:4)
简单的答案是你不能。深入研究HttpSOAPConnection代码,HttpURLConnection对象的本地实例用于与目标服务进行实际通信。这确实得到了httpResponse代码,但它或多或少完全隐藏了它来自调用者。您得出的结论是,如果您没有获得异常但返回的SOAPMessage包含SOAPFault,则返回代码为HttpURLConnection.HTTP_INTERNAL_ERROR(即500)。没有例外,没有SOAPFault意味着返回代码是200到206,所有这些都是" SUCCESS" - 遗憾的是,HttpURLConnection对象中HTTP标头的状态条目显式没有复制到返回的SOAPMessage中的MIMEHeaders ......
// Header field 0 is the status line so we skip it.
其他任何内容都会引发异常,代码将在异常的消息字段中的开括号之后开始,可能是三位数,很难准确,因为有人忘了关闭括号或任何其他分隔符消息之前......
throw new SOAPExceptionImpl(
"Bad response: ("
+ responseCode
+ httpConnection.getResponseMessage());
例如:
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Bad response: (502internal error - server connection terminated
依赖于异常中文本消息的格式化很可怕,但响应代码并未在其他任何地方公开。
答案 2 :(得分:1)
您可以通过MessageContext界面访问HTTP标头。
http://docs.oracle.com/javaee/5/api/javax/xml/ws/handler/MessageContext.html
最直接的方法可能是实现一个SOAPHandler,它可以让你访问MessageContext:
http://docs.oracle.com/cd/E15051_01/wls/docs103/webserv_adv/handlers.html#wp222394
但是,SOAP应用程序通常不应在HTTP状态代码上构建交互,因为它们是特定于传输的。
答案 3 :(得分:1)
另一种选择(java 8):
public class HttpResponseHandler implements SOAPHandler<SOAPMessageContext> {
private Logger log = Logger.create(HttpResponseHandler.class);
@Override
public boolean handleMessage(SOAPMessageContext context) {
boolean outboundProperty = (boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); // Response
if(!outboundProperty) {
int status = (int)context.get(MessageContext.HTTP_RESPONSE_CODE);
log.debug("HTTP status code = " + status);
}
return true;
}
}
// Usage : building your service
List<Handler> soapHandlers = new ArrayList();
soapHandlers.add(new HttpResponseHandler());
URL wsdlDocumentLocation = this.getClass().getResource("some_url");
Service service = Service.create(wsdlDocumentLocation, new QName("namespace", "servicename"));
service.setHandlerResolver(new HandlerResolver() {
public List<Handler> getHandlerChain(PortInfo portInfo) {
return soapHandlers;
}
});
BindingProvider provider = (BindingProvider)service.getPort(new QName("namespace", "portname"), serviceInterface);
provider.getRequestContext().put("javax.xml.ws.service.endpoint.address", this.endpointAddress);
provider.getRequestContext().put("com.sun.xml.ws.connect.timeout", connectTimeout);
provider.getRequestContext().put("com.sun.xml.ws.request.timeout", requestTimeout);
return provider;
答案 4 :(得分:0)
我确实有类似的要求,业务分析师希望记录与每个入站和出站soap调用相关的每个http响应代码。我的答案对Apache CXF 2.7.5有效。
您可以通过以下代码片段在javax.xml.ws.handler.soap.SoapHandler接口的实现中通过MessageContext接口访问http状态代码。
int status = (( javax.servlet.http.HttpServletResponse)messageContext.get("HTTP.RESPONSE")).getStatus();