You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在HTTP出站调用遇400、413等客户端错误时重发原/修改后消息

在Spring Integration Java DSL HTTP出站调用中处理400/413客户端错误并重发消息

要在Spring Integration Java DSL的HTTP出站调用场景中,针对400(请求错误)、413(负载过大)等客户端错误实现消息重发(原始消息或修改后消息),可以通过自定义重试通知(Advice)结合异常分类重试策略来实现,具体步骤如下:

1. 为HTTP出站端点配置重试通知

修改集成流,为HTTP出站的handle方法绑定自定义重试通知,让指定错误触发重试逻辑:

@Bean
private IntegrationFlow myChannel() {
    IntegrationFlowBuilder builder = 
             IntegrationFlows.from(queue)
              .handle(
                  // 配置HTTP POST请求示例
                  Http.outboundGateway("http://your-target-url")
                      .httpMethod(HttpMethod.POST)
                      .expectedResponseType(String.class), 
                  e -> e.advice(myRetryAdvice()) // 绑定自定义重试通知
              )
              .channel(MessageChannels.publishSubscribe(channel2));
   return builder.get();
}

2. 自定义异常分类重试策略,指定触发重试的客户端错误

创建专属重试策略,仅对400、413等目标客户端错误触发重试,其他错误直接跳过:

class ClientErrorClassifierRetryPolicy extends ExceptionClassifierRetryPolicy {
    public ClientErrorClassifierRetryPolicy() {
        // 配置最大重试次数:最多重试2次
        final SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy();
        simpleRetryPolicy.setMaxAttempts(2);

        // 异常分类逻辑:精准匹配目标错误码
        this.setExceptionClassifier(classifiable -> {
            if (classifiable instanceof HttpClientErrorException) {
                HttpStatus statusCode = ((HttpClientErrorException) classifiable).getStatusCode();
                // 仅对400、413错误触发重试
                if (statusCode == HttpStatus.BAD_REQUEST 
                        || statusCode == HttpStatus.PAYLOAD_TOO_LARGE) {
                    return simpleRetryPolicy;
                }
                // 其他客户端错误不重试
                return new NeverRetryPolicy();
            }
            // 非客户端错误直接终止
            return new NeverRetryPolicy();
        }); 
    }
}

3. 实现重试通知,支持修改消息后重发

重写RequestHandlerRetryAdvice的open方法,在重试前获取原始消息并修改,替换到重试上下文,让重试时使用新消息:

@Bean
public Advice myRetryAdvice() {
    RequestHandlerRetryAdvice retryAdvice = new RequestHandlerRetryAdvice() {
        @Override
        public <T, E extends Throwable> boolean open(RetryContext retryContext, RetryCallback<T, E> callback) {
            // 从重试上下文取出失败的原始消息
            Message<String> originalMsg = (Message<String>) retryContext.getAttribute(ErrorMessageUtils.FAILED_MESSAGE_CONTEXT);
            
            // 根据业务需求修改消息,比如压缩负载、修正请求参数
            Message<String> updatedMsg = MessageBuilder.fromMessage(originalMsg)
                    .setPayload("修改后的请求内容") // 示例:替换消息体
                    .build();
            
            // 将修改后的消息放回上下文,重试时会使用该消息
            retryContext.setAttribute(ErrorMessageUtils.FAILED_MESSAGE_CONTEXT, updatedMsg);
            
            return super.open(retryContext, callback);
        }
    };

    // 为重试通知绑定自定义的客户端错误重试策略
    retryAdvice.setRetryPolicy(new ClientErrorClassifierRetryPolicy());
    return retryAdvice;
}

4. 可选:错误通道处理重试失败的消息

如果所有重试都失败,可通过专属错误通道处理最终失败的消息:

@Bean
private IntegrationFlow defaultErrorChannel() {
    return IntegrationFlows.from("errorChannel")
            .handle(message -> {
                // 执行重试失败后的逻辑:记录日志、发送告警等
                ErrorMessage errorMessage = (ErrorMessage) message;
                System.err.println("重试全部失败,错误详情:" + errorMessage.getPayload().getMessage());
            })
            .get();
}

内容的提问来源于stack exchange,提问作者sophopile

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 04:31:19