Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring integration 筛选从http出站网关获取200状态的消息_Spring Integration - Fatal编程技术网

Spring integration 筛选从http出站网关获取200状态的消息

Spring integration 筛选从http出站网关获取200状态的消息,spring-integration,Spring Integration,我有一个消息流,如果GET HTTP调用(通过HTTP:outbound gateway)的结果是状态码200(即案例已经存在),我想在其中过滤/删除消息。换句话说,如果调用得到404(未找到),则流应该继续。理想情况下,任何其他状态代码或异常都应该转到errorHandler(现在) 我尝试调用一个使用http链的网关:带有请求处理程序建议链的出站网关,认为我可以捕获404,然后让事情继续,就好像它不是错误一样,然后在“过滤器”中测试状态码404。然而,有几个问题 onFailureExpre

我有一个消息流,如果GET HTTP调用(通过HTTP:outbound gateway)的结果是状态码200(即案例已经存在),我想在其中过滤/删除消息。换句话说,如果调用得到404(未找到),则流应该继续。理想情况下,任何其他状态代码或异常都应该转到errorHandler(现在)

我尝试调用一个使用http链的网关:带有请求处理程序建议链的出站网关,认为我可以捕获404,然后让事情继续,就好像它不是错误一样,然后在“过滤器”中测试状态码404。然而,有几个问题

  • onFailureExpression表达式未检测到状态代码404,日志显示HttpClientErrorException,所以可能未捕获异常
  • 我应该从onFailureExpression返回什么值?空或有效载荷还是#有效载荷?理想情况下,我希望HTTP调用之前的负载保持原样
  • 我需要TrapeException true吗
  • 奇怪没有更简单的方法?shame不能只在http:outbound gateway httpStatusCodes上声明允许的和被视为正常的代码。我认为错误通道和错误处理程序不是正确的方法,因为如果404状态代码为,我希望原始流继续。因此,将想要的常规行为放在错误流中,并且已经有了更高级别的错误处理程序,这看起来很奇怪
  • 2020-11-24 10:46:45060[main]调试org.springframework.web.client.restemplate-获取“的请求”http://localhost:9095/ccacase/V1/case/challenge/CHG123456789“导致404(未找到);调用错误处理程序
    2020-11-24 10:46:45134[main]DEBUG org.springframework.integration.channel.DirectChannel-postSend(sent=true)在“getChallengeCaseChannel”频道上,消息:GenericMessage[payload=uk.gov.voa.integration.ccacasecheck.json。CdbEvent@624b3544[id=22,eventType=MIGRATE\u CHALLENGE\u CASE,asstRef=,ccaCaseRef=CHG123456789,assessmentStatus=,settlementCode=,eventDateTime=2020-11-23T12:05,uarn=,sourceActivityId=,activityAction=,additionalProperties={},标头={replyChannel=org.springframework.messaging.core.GenericMessageTemplate$TemporaryReplyChannel@54f6b629,errorChannel=org.springframework.messaging.core.GenericMessageTemplate$TemporaryReplyChannel@54f6b629,originalPayload=uk.gov.voa.integration.ccacasecheck.json。CdbEvent@624b3544[id=22,eventType=MIGRATE\u CHALLENGE\u CASE,asstRef=,ccaCaseRef=CHG123456789,assessmentStatus=,settlementCode=,eventDateTime=2020-11-23T12:05,uarn=,sourceActivityId=,activityAction=,additionalProperties={}],message_id=22,history=cdbEventsAMQPChannel,routeEventChain,MigrateCallengeCaseEventChannel,MigrateCallengeCaseEventChain,statusFlow,GetChallengeCaseCaseChannel,id=6d99e890-fc56-74a8-1187-fbc3457685c8,timestamp=1606214804576}]
    2020-11-24 10:46:45135[main]DEBUG org.springframework.integration.handler.expressionevaluationMessageProcessor-SpEL表达式求值失败,出现异常。org.springframework.web.client.httpclienterror异常:404未找到
    原因:org.springframework.MessagingException:转换消息头失败;嵌套异常为org.springframework.messaging.MessageHandlingException:表达式计算失败:@statusFlow.exchange(#root).headers[http#u statusCode];嵌套异常为org.springframework.web.client.HttpClientErrorException:404未找到
    位于org.springframework.integration.transformer.HeaderEnricher.transform(HeaderEnricher.java:128)
    位于org.springframework.integration.transformer.MessageTransformingHandler.HandlerRequestMessage(MessageTransformingHandler.java:89)
    …还有72个
    原因:org.springframework.messaging.MessageHandlingException:表达式计算失败:@statusFlow.exchange(#root).headers[http_statusCode];嵌套异常为org.springframework.web.client.HttpClientErrorException:404未找到
    位于org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:143)
    位于org.springframework.integration.handler.ExpressionEvaluationMessageProcessor.processMessage(ExpressionEvaluationMessageProcessor.java:72)
    位于org.springframework.integration.transformer.support.expressionEvaluationHeaderValueMessageProcessor.processMessage(expressionEvaluationHeaderValueMessageProcessor.java:71)
    位于org.springframework.integration.transformer.HeaderEnricher.transform(HeaderEnricher.java:119)
    …还有73个
    原因:org.springframework.web.client.HttpClientErrorException:404未找到
    位于org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
    
    
    
    使用的解决方案是实现一个自定义ErrorHandler,它扩展默认值并覆盖hasError

    /**
     * To be used with an 'int-http:outbound-gateway' to make a HTTP call and allow a statusCode 404 
     * response to be treated as normal (as well as a 200 statusCode). 
     * Normally a statusCode 404 would throw a 
     * org.springframework.web.client.HttpClientErrorException: 404 Not Found
     * and expect the caller to deal with an error-channel.  
     * This allows processing to continue and subsequently test for a 404 response
     * and route differently 
     *
     */
    public class Allow404StatusCodeResponseHandler extends DefaultResponseErrorHandler  {
    
        /**
         * OVERRIDEN 
         * 
         * Indicate whether the given response has any errors.
         * <p>Implementations will typically inspect the
         * {@link ClientHttpResponse#getStatusCode() HttpStatus} of the response.
         * @param response the response to inspect
         * @return {@code true} if the response indicates an error; {@code false} otherwise
         * @throws IOException in case of I/O errors
         */
        @Override
        public boolean hasError(ClientHttpResponse response) throws IOException {
            int rawStatusCode = response.getRawStatusCode();
            return (rawStatusCode == 404 || rawStatusCode == 200) ? false : true;  // 404 to be treated as normal and testable downstream
        }
    
    }
    
    /**
    *与“int http:outbound gateway”一起使用,以进行http调用并允许状态码404
    *响应被视为正常(以及200状态代码)。
    *通常情况下,状态码404会抛出
    *org.springframework.web.client.HttpClientErrorException:未找到404
    *并期望调用者处理错误通道。
    *这允许处理继续并随后测试404响应
    *而且路线不同
    *
    */
    公共类Allow404StatusCodeResponseHandler扩展了DefaultResponseErrorHandler{
    /**
    *凌驾
    * 
    *指示给定的响应是否有任何错误。
    
    <int:chain id="migrateChallengeCaseEventChain" input-channel="migrateChallengeCaseEventChannel">
    
            <int:header-enricher>                                
                <int:header name="caseStatusCode" expression="@statusFlow.exchange(#root).headers[http_statusCode]" />    
            </int:header-enricher>
            
            <!-- to check http_statusCode header and drop any message with found 200 statusCode -->
            <int:filter ref="status200Filter"/>  
            
            <int:transformer ref="migrateChallengeCaseTransformer" />
            <int:transformer ref="jsonValidationTransformer" />
            <int:object-to-json-transformer object-mapper="springJacksonObjectMapper" />
            <int:header-enricher>
                 <int:header name="contentType" value="application/json;charset=UTF-8" overwrite="true"/>
            </int:header-enricher>  
            <int-amqp:outbound-channel-adapter 
                amqp-template="amqpTemplate" exchange-name="cdbEvents.exchange" 
                routing-key="migrateCdbCcaChallengeCase.request.queue.binding" />
        </int:chain>    
        
        <int:gateway id="statusFlow" default-request-channel="getChallengeCaseChannel" />  
        
        <int:channel id="getChallengeCaseChannel" />
        
        <!-- Call API to see if Case already exists, 200 status code we want to filter/drop message   -->
        <int:chain id="getChallengeCaseChain" input-channel="getChallengeCaseChannel">
            <int-http:outbound-gateway id="httpOutboundGatewayChallengeCaseGet"     
                                expected-response-type="java.lang.String"                                           
                                http-method="GET"   charset="UTF-8"
                                extract-request-payload="true"  
                                request-factory="httpRequestFactory"                    
                                url="${mule.case.data.service.uri}/${case.challenge.subpath}/{ccaCaseRefValue}">
                <int-http:uri-variable name="ccaCaseRefValue" expression="headers['originalPayload'].ccaCaseRef"/>  
                <int-http:request-handler-advice-chain>
                        <bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
                            <!-- If true, the result of evaluating the onFailureExpression will be returned as the result -->
                            <property name="returnFailureExpressionResult" value="true" />
                            <property name="onSuccessExpression" value="payload" />
                            <!-- If true, any exception will be caught and null returned. Default false -->
                             <property name="trapException" value="true" /> 
                            <!-- Set the expression to evaluate against the root message after a failed handler invocation. The exception is available as the variable #exception. Defaults to payload, if failureChannel is configured. -->
                            <property name="onFailureExpression"  value="#exception.cause.statusCode == 404 ? payload : #exception"/> 
                            <!-- Set the channel name to which to send the ErrorMessage after evaluating the failure expression. -->
                            <!-- <property name="failureChannel" ref="#headers['replyChannel']" />  -->
                        </bean>
                    </int-http:request-handler-advice-chain>
            </int-http:outbound-gateway>
        
        </int:chain>    
    
    /**
     * To be used with an 'int-http:outbound-gateway' to make a HTTP call and allow a statusCode 404 
     * response to be treated as normal (as well as a 200 statusCode). 
     * Normally a statusCode 404 would throw a 
     * org.springframework.web.client.HttpClientErrorException: 404 Not Found
     * and expect the caller to deal with an error-channel.  
     * This allows processing to continue and subsequently test for a 404 response
     * and route differently 
     *
     */
    public class Allow404StatusCodeResponseHandler extends DefaultResponseErrorHandler  {
    
        /**
         * OVERRIDEN 
         * 
         * Indicate whether the given response has any errors.
         * <p>Implementations will typically inspect the
         * {@link ClientHttpResponse#getStatusCode() HttpStatus} of the response.
         * @param response the response to inspect
         * @return {@code true} if the response indicates an error; {@code false} otherwise
         * @throws IOException in case of I/O errors
         */
        @Override
        public boolean hasError(ClientHttpResponse response) throws IOException {
            int rawStatusCode = response.getRawStatusCode();
            return (rawStatusCode == 404 || rawStatusCode == 200) ? false : true;  // 404 to be treated as normal and testable downstream
        }
    
    }
    
    /**
     * Spring's default implementation of the {@link ResponseErrorHandler} interface.
     *
     * <p>This error handler checks for the status code on the
     * {@link ClientHttpResponse}. Any code in the 4xx or 5xx series is considered
     * to be an error. This behavior can be changed by overriding
     * {@link #hasError(HttpStatus)}. Unknown status codes will be ignored by
     * {@link #hasError(ClientHttpResponse)}.
     *
     * <p>See {@link #handleError(ClientHttpResponse)} for more details on specific
     * exception types.
     *
     * @author Arjen Poutsma
     * @author Rossen Stoyanchev
     * @author Juergen Hoeller
     * @since 3.0
     * @see RestTemplate#setErrorHandler
     */
    public class DefaultResponseErrorHandler implements ResponseErrorHandler {