AXIS2:Axisfault后重试Web服务调用



环境:ubuntu x86_64,jdk 1.7.0_80,tomcat 7.0.64

我正在从事某些AXIS2 Web服务,我希望能够在Web服务调用后捕获AXFOULT异常(例如,当HTTP 404、500或SSL错误被抛出时(,执行某些任务(按顺序执行尝试自动解决任何配置问题(,然后仅一旦使用相同的Web服务请求重试。我知道AXIS2阶段和处理程序以及如何在输液或外faultflow阶段触发处理程序,但是我认为它不符合目的,因为我只想进行一次重试,例如,如果我收到的话,重试的另一个axeft,我希望它升级并让整个请求失败(这意味着系统在第一次失败后进行自我配置的努力不足以解决问题,因此需要Sysadmin干预(。我认为,如果自我配置无法解决问题,使用处理程序将将请求带入无限循环。尽管如此,我尝试了它,但找不到进行重试的方法。因此,我正在尝试在触发请求的代码中进行通常的尝试/捕捉。

在我的存根类中,我创建了具有其选项,必要标题的服务,然后我执行请求。这是代码的相关部分:

public class RespondingGateway_ServiceStub extends org.apache.axis2.client.Stub {

       private void populateAxisService() {
        // creating the Service with a unique name
        _service = new org.apache.axis2.description.AxisService("RespondingGateway_Service" + getUniqueSuffix());
        addAnonymousOperations();
        // creating the operations
        org.apache.axis2.description.AxisOperation __operation;
        _operations = new org.apache.axis2.description.AxisOperation[1];
        __operation = new org.apache.axis2.description.OutInAxisOperation();
        __operation.setName(new javax.xml.namespace.QName(XCPDConstants.SOAP_HEADERS.NAMESPACE_URI, XCPDConstants.SOAP_HEADERS.NAMESPACE_REQUEST_LOCAL_PART));
        _service.addOperation(__operation);
        _operations[0] = __operation;
        }
        // populates the faults
        private void populateFaults() {
        }
        /**
         * Constructor that takes in a configContext
         */
        public RespondingGateway_ServiceStub(org.apache.axis2.context.ConfigurationContext configurationContext, String targetEndpoint) {
            this(configurationContext, targetEndpoint, false);
        }
        /**
         * Constructor that takes in a configContext and useseperate listner
         */
        public RespondingGateway_ServiceStub(org.apache.axis2.context.ConfigurationContext configurationContext, String targetEndpoint, boolean useSeparateListener) {
            // To populate AxisService
            populateAxisService();
            populateFaults();
            try {
                _serviceClient = new org.apache.axis2.client.ServiceClient(configurationContext, _service);
            } catch (AxisFault ex) {
                throw new RuntimeException(ex);
            }
            _serviceClient.getOptions().setTo(new org.apache.axis2.addressing.EndpointReference(targetEndpoint));
            _serviceClient.getOptions().setUseSeparateListener(useSeparateListener);
            _serviceClient.getOptions().setTimeOutInMilliSeconds(180000); //Wait time after which a client times out in a blocking scenario: 3 minutes
            // Set the soap version
            _serviceClient.getOptions().setSoapVersionURI(org.apache.axiom.soap.SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);
            MultiThreadedHttpConnectionManager multiThreadedHttpConnectionManager = new MultiThreadedHttpConnectionManager();
            HttpConnectionManagerParams params = new HttpConnectionManagerParams();
            params.setDefaultMaxConnectionsPerHost(20);
            multiThreadedHttpConnectionManager.setParams(params);
            HttpClient httpClient = new HttpClient(multiThreadedHttpConnectionManager);
            this._getServiceClient().getServiceContext().getConfigurationContext().setProperty(HTTPConstants.REUSE_HTTP_CLIENT, false);
            this._getServiceClient().getServiceContext().getConfigurationContext().setProperty(HTTPConstants.CACHED_HTTP_CLIENT, httpClient);
            this._getServiceClient().getServiceContext().getConfigurationContext().setProperty(HTTPConstants.AUTO_RELEASE_CONNECTION, false);
        }
    public org.hl7.v3.PRPAIN201306UV02 respondingGateway_PRPA_IN201305UV02(PRPAIN201305UV02 pRPA_IN201305UV02, Assertion idAssertion) {
        org.apache.axis2.client.OperationClient operationClient = _serviceClient.createClient(_operations[0].getName());
        /* set the message context with that soap envelope */
        org.apache.axis2.context.MessageContext messageContext = new org.apache.axis2.context.MessageContext();
        messageContext.setEnvelope(env);
        /* add the message contxt to the operation client */
        operationClient.addMessageContext(messageContext);
        try {
            operationClient.execute(true);
        } catch (AxisFault e) {
        // perform internal tasks
        // retry the request
        // if we get another AxisFault we just let it escalate
        }
    }

使用此代码,我能够捕获AXFOULT并执行内部任务。但是后来我不知道如何进行重试。我尝试使用AXIS2 API,包括再次致电catch块内的operationClient.execute(true),但没有成功:

try {
        operationClient.execute(true);
    } catch (AxisFault e) {
       operationClient.complete(messageContext);
       LOG.debug("Adding message context again");
       messageContext.resetExecutedPhases();
       operationClient.addMessageContext(messageContext);
       LOG.debug("Executing");
       operationClient.execute(true);
       LOG.debug("Successfully retried the operation!");

我有以下错误:

ERROR 2017-04-19 12:59:03,832 eu.epsos.pt.cc.ClientConnectorServiceMessageReceiverInOut invokeBusinessLogic.385  - A message was added that is not valid. However, the operation context was complete.
java.lang.RuntimeException: A message was added that is not valid. However, the operation context was complete.
    at tr.com.srdc.epsos.ws.xcpd.client.RespondingGateway_ServiceStub.respondingGateway_PRPA_IN201305UV02(RespondingGateway_ServiceStub.java:445)
    at tr.com.srdc.epsos.ws.xcpd.client.RespondingGateway_RequestSender.sendRequest(RespondingGateway_RequestSender.java:80)
    at tr.com.srdc.epsos.ws.xcpd.client.RespondingGateway_RequestSender.respondingGateway_PRPA_IN201305UV02(RespondingGateway_RequestSender.java:69)
    at eu.epsos.pt.ws.client.xcpd.XcpdInitGateway.patientDiscovery(XcpdInitGateway.java:59)
    at eu.epsos.pt.cc.stub.IdentificationService.findIdentityByTraits(IdentificationService.java:72)
    at eu.epsos.pt.cc.ClientConnectorServiceSkeleton.queryPatient(ClientConnectorServiceSkeleton.java:107)
    at eu.epsos.pt.cc.ClientConnectorServiceMessageReceiverInOut.invokeBusinessLogic(ClientConnectorServiceMessageReceiverInOut.java:215)
    at org.apache.axis2.receivers.AbstractInOutMessageReceiver.invokeBusinessLogic(AbstractInOutMessageReceiver.java:40)
    at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:114)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:181)
    at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:172)
    at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:146)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.axis2.AxisFault: A message was added that is not valid. However, the operation context was complete.
    at org.apache.axis2.description.OutInAxisOperation.addMessageContext(OutInAxisOperation.java:78)
    at org.apache.axis2.context.OperationContext.addMessageContext(OperationContext.java:218)
    at org.apache.axis2.description.AxisOperation.registerOperationContext(AxisOperation.java:286)
    at org.apache.axis2.description.OutInAxisOperationClient.addMessageContext(OutInAxisOperation.java:132)
    at tr.com.srdc.epsos.ws.xcpd.client.RespondingGateway_ServiceStub.respondingGateway_PRPA_IN201305UV02(RespondingGateway_ServiceStub.java:302)
    ... 33 more

我试图搜索解决方案,但没有成功。我认为这应该是再次重置Axis2内部Web服务状态和阶段的问题,但我不知道如何解决此问题。

我找到了解决方案。基本上,我要创建一个新的操作客户,Soapenvelope和MessageContext,然后再次执行请求:

try {
    operationClient.execute(true);
} catch (AxisFault e) {
    LOG.error("Axis Fault error: " + e.getMessage());
    /* we need a new OperationClient, otherwise we'll face the error "A message was added that is not valid. However, the operation context was complete." */
    OperationClient newOperationClient = _serviceClient.createClient(_operations[0].getName());
    newOperationClient.getOptions().setAction(XCPDConstants.SOAP_HEADERS.REQUEST_ACTION);
    newOperationClient.getOptions().setExceptionToBeThrownOnSOAPFault(true);
    addPropertyToOperationClient(newOperationClient, org.apache.axis2.description.WSDL2Constants.ATTR_WHTTP_QUERY_PARAMETER_SEPARATOR, "&");
    SOAPFactory newSoapFactory = getFactory(newOperationClient.getOptions().getSoapVersionURI());
    org.apache.axiom.soap.SOAPEnvelope newEnv;
    newEnv = toEnvelope(newSoapFactory,
                pRPA_IN201305UV02,
                optimizeContent(new javax.xml.namespace.QName(XCPDConstants.SOAP_HEADERS.NAMESPACE_URI, XCPDConstants.SOAP_HEADERS.NAMESPACE_REQUEST_LOCAL_PART)));
    _serviceClient.addHeadersToEnvelope(newEnv);
    /* we create a new Message Context with the new SOAP envelope */
    org.apache.axis2.context.MessageContext newMessageContext = new org.apache.axis2.context.MessageContext();
    newMessageContext.setEnvelope(newEnv);
    /* add the new message contxt to the new operation client */
    newOperationClient.addMessageContext(newMessageContext);
    /* we retry the request */
    newOperationClient.execute(true);
}

最新更新