关于使⽤Axis2webrvice处理Fault响应时抛org.apache.axis。。。使⽤Axis2这个框架进⾏webrvice协议通讯,期间出了个问题,我(CLIENT)请求后,当服务端返回符合协议的SOAP异常报⽂,例如<soap:fault> ...
我的程序直接抛org.apache.axis2.AxisFault异常,导致连服务端给我们的报⽂都没有接收成功。
--请注意,是我连报⽂都没有接收成功,⽽不是接收成功后我解析失败了。
[java]
1. try {
2. ServiceClient rviceClient = new ServiceClient();
3. Options options = new Options();
4. //设置超时时间,单位毫秒
5. options.tTimeOutInMilliSeconds(this.wsTimeOut);
6. options.tTransportInProtocol(Constants.TRANSPORT_HTTP);
7. options.tTo(new EndpointReference(this.wsEndpointAddress));
8. options.tSoapVersionURI(org.apache.axiom.soap.SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);
9. options.tAction(this.wsMethod);
10. MessageContext requetMessageContext = new MessageContext();
11. SOAPEnvelope env = RequestEnvelope();
12. log.info("version : "+ Version().getEnvelopeURI());
13. requetMessageContext.tEnvelope(env);
14.
15. OperationClient opClient = ateClient(ServiceClient.ANON_OUT_IN_OP);
16. opClient.addMessageContext(requetMessageContext);
17. opClient.tOptions(options);
18. ute(true);
19. MessageContext rspMC = MessageContext("In");
20. respon = Envelope().getBody().getFirstElement();
21. log.info("应答报⽂: "+ Envelope());
22. } catch (AxisFault e) {
23. RspDesc = "xxxxx";
24. ("soapDispatch AxisFault!");
25. throw e;
26. } catch (Exception e) {
27. RspDesc = "xxxxxxxxxxxxx!";
28. ("soapDispatch Exception!");
29. throw e;
30. }
try {
ServiceClient rviceClient = new ServiceClient();
Options options = new Options();
//设置超时时间,单位毫秒
options.tTimeOutInMilliSeconds(this.wsTimeOut);
options.tTransportInProtocol(Constants.TRANSPORT_HTTP);
options.tTo(new EndpointReference(this.wsEndpointAddress));
options.tSoapVersionURI(org.apache.axiom.soap.SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);
options.tAction(this.wsMethod);
MessageContext requetMessageContext = new MessageContext();
SOAPEnvelope env = RequestEnvelope();
log.info("version : "+ Version().getEnvelopeURI());
requetMessageContext.tEnvelope(env);
OperationClient opClient = ateClient(ServiceClient.ANON_OUT_IN_OP);
opClient.addMessageContext(requetMessageContext);
opClient.tOptions(options);
MessageContext rspMC = MessageContext("In");
respon = Envelope().getBody().getFirstElement();
log.info("应答报⽂: "+ Envelope());
} catch (AxisFault e) {
<("soapDispatch AxisFault!");
throw e;
} catch (Exception e) {
<("soapDispatch Exception!");
throw e;
}
当执⾏到发送请求ute(true);
服务端成功返回格式正常的SOAP异常报⽂,此时程序直接抛异常,⾛不到下⾯rspMC的获取,也就拿不到响应报⽂。炎热清颗粒
经过⼀段时间的查看Axis2源码,终于找到原因。
从ute(true); ⼊⼿,可以看到
[java]
1. public final void execute(boolean block) throws AxisFault {
2. this.sc.);
3. uteImpl(block);
4. }
public final void execute(boolean block) throws AxisFault {
this.sc.);
}
再看uteImpl(block);
[java]
1. public void executeImpl(boolean block) throws AxisFault {
2. if(log.isDebugEnabled()) {
3. log.debug("Entry: OutInAxisOperationClient::execute, " + block);
4. }
5.
6. pleted) {
7. throw new Message("mepiscomplted"));
8. } el {
9. ConfigurationContext cc = ConfigurationContext();
10. MessageContext mc = MessageContext("Out");
11. if(mc == null) {
12. throw new Message("outmsgctxnull"));
13. } el {
14. this.prepareMessageContext(cc, mc);
15. if(TransportIn() == null && mc.getTransportIn() == null) {
16. mc.tTransportIn(ClientUtils.AxisConfiguration(), this.options, mc));
17. } el TransportIn() == null) {
18. mc.tTransportIn(TransportIn());
19. }
20.
21. boolean uAsync = fal;
22. if(!mc.getOptions().isUSeparateListener()) {
23. Boolean replyTo = (Property("UAsyncOperations");
什么样的轮子只转不走24. if(log.isDebugEnabled()) {
25. log.debug("OutInAxisOperationClient: uAsyncOption " + replyTo);
26. }
27.
28. if(replyTo != null) {
29. uAsync = replyTo.booleanValue();
30. }
玉米面糊糊的做法31. }
32.
33. EndpointReference replyTo1 = mc.getReplyTo();
34. if(replyTo1 != null) {
35. if(replyTo1.hasNoneAddress()) {
36. throw new Address() + "" + " can not be ud with OutInAxisOperationClient , ur either " + "fireAndForget or ndRobust)");
37. }
38.
安河桥间奏简谱39. if(replyTo1.isWSAddressingAnonymous() && AllReferenceParameters() != null) {
40. mc.tProperty("includeOptionalHeaders", Boolean.TRUE);
41. }
42.
43. String customReplyTo = (String)Property(Options.CUSTOM_REPLYTO_ADDRESS);
44. if(!Options.CUSTOM_REPLYTO_ADDRESS_TRUE.equals(customReplyTo) && !replyTo1.hasAnonymousAddress()) {
45. uAsync = true;
46. }
47. }
48.
49. if(!uAsync && !mc.getOptions().isUSeparateListener()) {
50. if(block) {
51. this.nd(mc);
52. pleted = true;
53. } el {
54. ConfigurationContext().getThreadPool().execute(new OutInAxisOperationClient.NonBlockingInvocationWorker(this.callback, mc, this.axisCallback));
55. }
56. } el {
57. this.ndAsync(uAsync, mc);
58. }
59.
60. }
61. }
62. }
public void executeImpl(boolean block) throws AxisFault {
if(log.isDebugEnabled()) {
log.debug("Entry: OutInAxisOperationClient::execute, " + block);
}
pleted) {
throw new Message("mepiscomplted"));
} el {
ConfigurationContext cc = ConfigurationContext();
MessageContext mc = MessageContext("Out");
if(mc == null) {
throw new Message("outmsgctxnull"));
} el {
this.prepareMessageContext(cc, mc);
if(TransportIn() == null && mc.getTransportIn() == null) {
mc.tTransportIn(ClientUtils.AxisConfiguration(), this.options, mc));
} el TransportIn() == null) {
mc.tTransportIn(TransportIn());
}
boolean uAsync = fal;
if(!mc.getOptions().isUSeparateListener()) {
Boolean replyTo = (Property("UAsyncOperations");
if(log.isDebugEnabled()) {
log.debug("OutInAxisOperationClient: uAsyncOption " + replyTo);
}
if(replyTo != null) {
uAsync = replyTo.booleanValue();
}
}
EndpointReference replyTo1 = mc.getReplyTo();
if(replyTo1 != null) {
if(replyTo1.hasNoneAddress()) {
throw new Address() + "" + " can not be ud with OutInAxisOperationClient , ur either " + "fireAndForget or ndRobust)");
}
if(replyTo1.isWSAddressingAnonymous() && AllReferenceParameters() != null) {
mc.tProperty("includeOptionalHeaders", Boolean.TRUE);
}
String customReplyTo = (String)Property(Options.CUSTOM_REPLYTO_ADDRESS);
if(!Options.CUSTOM_REPLYTO_ADDRESS_TRUE.equals(customReplyTo) && !replyTo1.hasAnonymousAddress()) {
uAsync = true;接力奋斗
}
}
if(!uAsync && !mc.getOptions().isUSeparateListener()) {
if(block) {
this.nd(mc);
} el {
ConfigurationContext().getThreadPool().execute(new OutInAxisOperationClient.NonBlockingInvocationWorker(this.callback, mc, this.axisCallback));
}
} el {
this.ndAsync(uAsync, mc);
}
}
}
}
进nd(mc)⽅法
[java]
1. protected MessageContext nd(MessageContext msgContext) throws AxisFault {
2. MessageContext responMessageContext = ConfigurationContext().createMessageContext();
3. responMessageContext.tServerSide(fal);
4. responMessageContext.OperationContext());
5. responMessageContext.tOptions(new Options(this.options));父亲和女儿
6. responMessageContext.MessageID());
7. this.addMessageContext(responMessageContext);
8. responMessageContext.ServiceContext());
9. responMessageContext.tAxisMessage(Message("In"));
10. AxisEngine.nd(msgContext);
11. responMessageContext.tDoingREST(msgContext.isDoingREST());
12. responMessageContext.tProperty("TRANSPORT_HEADERS", Property("TRANSPORT_HEADERS"));
13. responMessageContext.tProperty(HTTPConstants.MC_HTTP_STATUS_CODE, Property(HTTPConstants.MC_HTTP_STATUS_CODE));
14. responMessageContext.tProperty("TRANSPORT_IN", Property("TRANSPORT_IN"));
15. responMessageContext.TransportIn());
16. responMessageContext.TransportOut());
17. this.handleRespon(responMessageContext);
18. return responMessageContext;
19. }怎么修改微信铃声
protected MessageContext nd(MessageContext msgContext) throws AxisFault {
MessageContext responMessageContext = ConfigurationContext().createMessageContext();
responMessageContext.tServerSide(fal);
responMessageContext.OperationContext());
responMessageContext.tOptions(new Options(this.options));
responMessageContext.MessageID());
this.addMessageContext(responMessageContext);
responMessageContext.ServiceContext());
responMessageContext.tAxisMessage(Message("In"));
AxisEngine.nd(msgContext);
responMessageContext.tDoingREST(msgContext.isDoingREST());
responMessageContext.tProperty("TRANSPORT_HEADERS", Property("TRANSPORT_HEADERS"));
responMessageContext.tProperty(HTTPConstants.MC_HTTP_STATUS_CODE, Property(HTTPConstants.MC_HTTP_STATUS_CODE));
responMessageContext.tProperty("TRANSPORT_IN", Property("TRANSPORT_IN"));
responMessageContext.TransportIn());
responMessageContext.TransportOut());
this.handleRespon(responMessageContext);
return responMessageContext;
}
这⾥就是发送请求并接收响应的地⽅再看倒数第⼆⾏this.handleRespon(responMessageContext);
[java]
1. protected void handleRespon(MessageContext responMessageContext) throws AxisFault {
2. responMessageContext.tSoapAction((String)null);
3. SOAPEnvelope renvelope;
4. Envelope() == null) {
5. renvelope = ateSOAPMessage(responMessageContext);
6. if(renvelope == null) {
7. throw new Message("blockingInvocationExpectsRespon"));
8. }
9.
10. responMessageContext.tEnvelope(renvelope);
11. }
12.
13. renvelope = Envelope();
14. if(renvelope != null) {
15. ive(responMessageContext);
16. ReplyTo() != null) {
17. this.sc.ReplyTo());
18. }
19.
20. renvelope = Envelope();
21. if((renvelope.hasFault() || responMessageContext.isProcessingFault()) && this.options.isExceptionToBeThrownOnSOAPFault()) {
22. InboundFaultFromMessageContext(responMessageContext);
23. }
24. }
25.
26. }
protected void handleRespon(MessageContext responMessageContext) throws AxisFault {
responMessageContext.tSoapAction((String)null);
SOAPEnvelope renvelope;
Envelope() == null) {
renvelope = ateSOAPMessage(responMessageContext);
动词不定式if(renvelope == null) {
throw new Message("blockingInvocationExpectsRespon"));
}
responMessageContext.tEnvelope(renvelope);
}
renvelope = Envelope();
if(renvelope != null) {
ReplyTo() != null) {
this.sc.ReplyTo());
}
renvelope = Envelope();
if((renvelope.hasFault() || responMessageContext.isProcessingFault()) && this.options.isExceptionToBeThrownOnSOAPFault()) {
InboundFaultFromMessageContext(responMessageContext);
}
}
}
这时,我们可以看到⼀个很有趣的⽅法, if((renvelope.hasFault() || responMessageContext.isProcessingFault()) 总算是跟我们的异常报⽂有关了。跟进去看⼀下
[java]
1. public boolean hasFault() {
2. QName payloadQName = PayloadQName_Optimized();
3. if(payloadQName != null && "Fault".LocalPart())) {
4. String body1 = NamespaceURI();
5. return "lsoap/soap/envelope/".equals(body1) || "www.w3/2003/05/soap-envelope".equals(body1);
6. } el {
7. SOAPBody body = Body();
8. return body == null?fal:body.hasFault();
9. }
10. }
public boolean hasFault() {
QName payloadQName = PayloadQName_Optimized();
if(payloadQName != null && "Fault".LocalPart())) {
String body1 = NamespaceURI();
return "lsoap/soap/envelope/".equals(body1) || "www.w3/2003/05/soap-envelope".equals(body1);
} el {
SOAPBody body = Body();
return body == null?fal:body.hasFault();
}
}
可以看到Axis2的内部处理机制,就是⼀但发现响应报⽂有Fault节点,它就要抛异常。总算找到源头了那要如何解决这个问题我们可以看到 if((renvelope.hasFault() || responMessageContext.isProcessingFault()) && this.options.isExceptionToBeThrownOnSOAPFault()) { throw
[java]
1. options.tExceptionToBeThrownOnSOAPFault(fal);
options.tExceptionToBeThrownOnSOAPFault(fal);
就不抛异常了,能够正常获取并解析响应报⽂。总结:⼀切的害怕源于对代码的神秘,未知,当你把它当成⾃⼰写的代码,去反编译,去阅读,那就不会再害怕!