如何从SOAPConnection.call()
的结果中获取HTTP状态?
SOAP HTTP 遵循 HTTP 状态代码的语义,用于在 HTTP 中传递状态信息。例如,2xx 状态码表明客户端请求包括 SOAP 组件已成功接收、理解和接受等。
如果处理请求时出现 SOAP 错误,则 SOAP HTTP 服务器必须发出 HTTP 500“内部服务器错误”响应,并在响应中包含一个包含 SOAP 故障元素(参见第4.4节)指示 SOAP 处理错误的 SOAP 消息。
并且从API中的SOAPFault文档中得知:
SOAPBody 对象中的一个元素,包含错误和/或状态信息。这些信息可能涉及到 SOAPMessage 对象中的错误,或者与消息内容本身无关的问题。
因此,可能的答案为
SoapMessage soapMessage = null;
soapMessage = MySOAPConnection.call(...);
soapMessage.getSOAPPart().getEnvelope().getBody().getFault().getFaultCode();
对我回答有所帮助的参考资料包括:
// 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
在异常处理中依赖文本消息的格式非常糟糕,但是响应代码在其他任何地方都没有暴露出来。
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;
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状态码上进行交互,因为这些状态码是传输特定的。我确实有与这个问题相同的要求,业务分析师希望记录与每个传入和传出的SOAP调用相关的每个HTTP响应代码。我的答案适用于Apache CXF 2.7.5。
您可以通过在javax.xml.ws.handler.soap.SoapHandler接口的实现中使用以下代码片段来访问HTTP状态码。
int status = (( javax.servlet.http.HttpServletResponse)messageContext.get("HTTP.RESPONSE")).getStatus();
http状态
与200 OK
不同,您将收到SOAPException
。 - Andremoniy