1.引言

有时在调用Web服务时,我们可能有兴趣在发生错误的情况下重试该操作。 使用Spring Integration时,我们可以使用RequestHandlerRetryAdvice类实现此功能。 此类将使我们在放弃并引发异常之前重试指定次数的操作。 这篇文章将向您展示如何完成此任务。

测试应用程序将调用Web服务,如果响应失败,它将等待指定的时间,然后重试,直到收到响应或达到重试限制为止。 如果达到限制,失败的请求将被存储到数据库中。 主要,这篇文章显示以下示例:

  • 使用出站网关调用Web服务
  • 配置重试建议以在必要时重试该操作
  • MongoDB集成。

该应用程序的源代码可以在github上找到。

您还可以在github上获取由应用程序调用的Web服务项目的源代码。

2.Web服务调用

用例 :客户端调用Web服务并接收响应。

该请求通过“系统入口”网关进入消息传递系统。 然后,它到达出站网关,调用Web服务并等待响应。 收到响应后,将其发送到响应通道。

上图是此配置的结果:

<context:component-scan base-package="xpadro.spring.integration" /><!-- Initial service request -->
<int:gateway id="systemEntry" default-request-channel="requestChannel"service-interface="xpadro.spring.integration.gateway.ClientService" /><int:channel id="requestChannel"><int:queue />
</int:channel><int-ws:outbound-gateway id="marshallingGateway"request-channel="requestChannel" reply-channel="responseChannel"uri="http://localhost:8080/spring-ws/orders" marshaller="marshaller"unmarshaller="marshaller"><int:poller fixed-rate="500" />
</int-ws:outbound-gateway><oxm:jaxb2-marshaller id="marshaller" contextPath="xpadro.spring.integration.types" /><!-- Service is running - Response received -->
<int:channel id="responseChannel" /><int:service-activator ref="clientServiceActivator" method="handleServiceResult" input-channel="responseChannel" />

映射到响应通道的是一个服务激活器,它仅记录结果。

TestInvocation.java:将请求发送到入口网关

@ContextConfiguration({"classpath:xpadro/spring/integration/config/int-config.xml","classpath:xpadro/spring/integration/config/mongodb-config.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class TestInvocation {private Logger logger = LoggerFactory.getLogger(this.getClass());@Autowiredprivate ClientService service;@Testpublic void testInvocation() throws InterruptedException, ExecutionException {logger.info("Initiating service request...");ClientDataRequest request = new ClientDataRequest();request.setClientId("123");request.setProductId("XA-55");request.setQuantity(new BigInteger("5"));service.invoke(request);logger.info("Doing other stuff...");Thread.sleep(60000);}
}

使用此配置,如果服务调用失败,则将引发MessagingException并将其发送到错误通道。 在下一节中,我们将添加重试配置。

3.添加重试建议

用例 :初始请求失败,因为该服务未激活。 我们将重试该操作,直到从服务收到响应为止。

在这种情况下,我们需要将重试建议添加到Web服务出站网关:

<int-ws:outbound-gateway id="marshallingGateway" interceptor="clientInterceptor"request-channel="requestChannel" reply-channel="responseChannel"uri="http://localhost:8080/spring-ws/orders" marshaller="marshaller"unmarshaller="marshaller"><int:poller fixed-rate="500" /><int-ws:request-handler-advice-chain><ref bean="retryAdvice" /></int-ws:request-handler-advice-chain>
</int-ws:outbound-gateway>

现在,Web服务出站网关会将调用委派给重试建议,重试建议将按指定的次数尝试操作多次,直到从服务获得响应为止。 让我们定义重试建议:

<bean id="retryAdvice" class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice" ><property name="retryTemplate"><bean class="org.springframework.retry.support.RetryTemplate"><property name="backOffPolicy"><bean class="org.springframework.retry.backoff.FixedBackOffPolicy"><property name="backOffPeriod" value="4000" /></bean></property><property name="retryPolicy"><bean class="org.springframework.retry.policy.SimpleRetryPolicy"><property name="maxAttempts" value="4" /></bean></property></bean></property>
</bean>

为了实现其目标,建议使用RetryTemplate,该模板由Spring Retry项目提供。 我们可以通过定义退避重试策略来自定义其行为。

退避政策 :在每次重试之间建立一段时间。 更有趣的类型是:

  • FixedBackOffPolicy :在我们的示例中使用。 每次重试之间将等待相同的指定时间。
  • ExponentialBackOffPolicy :从确定的时间量开始,它将使每次重试的时间加倍。 您可以通过建立乘数来更改默认行为。

重试策略 :确定将重试失败操作的次数。 一些类型:

  • SimpleRetryPolicy :在我们的示例中使用。 指定重试次数限制。
  • ExceptionClassifierRetryPolicy :允许我们根据引发的异常来建立不同的maxAttempts。
  • TimeoutRetryPolicy :将继续重试,直到达到超时为止。

4,不走运,记录失败的请求

用例 :服务将无法恢复,无法将请求存储到数据库中。

配置的最后部分如下:

<!-- Log failed invocation -->
<int:service-activator ref="clientServiceActivator" method="handleFailedInvocation" input-channel="errorChannel" output-channel="logChannel" /><int:channel id="logChannel" /><bean id="mongoDbFactory" class="org.springframework.data.mongodb.core.SimpleMongoDbFactory"><constructor-arg><bean class="com.mongodb.Mongo"/></constructor-arg><constructor-arg value="test"/>
</bean><int-mongodb:outbound-channel-adapter id="mongodbAdapter" channel="logChannel"collection-name="failedRequests" mongodb-factory="mongoDbFactory" />

订阅错误通道的服务激活器将检索失败的消息并将其发送到出站适配器,出站适配器会将其插入到mongoDB数据库中。 服务激活器:

public Message<?> handleFailedInvocation(MessagingException exception) {logger.info("Failed to succesfully invoke service. Logging to DB...");return exception.getFailedMessage();
}

如果我们未能成功从服务获得响应,则该请求将存储到数据库中:

六,结论

我们已经了解了Spring Integration如何从Spring Retry项目获得支持以实现操作的重试。 我们使用了int-ws:request-handler-advice-chain ,但是'int'命名空间也支持此元素,以将该功能添加到其他类型的端点。

参考:在XavierPadró的Blog博客上,我们的JCG合作伙伴 Xavier Padro 使用RequestHandlerRetryAdvice重试了Web服务操作 。

翻译自: https://www.javacodegeeks.com/2014/02/retry-web-service-operations-with-requesthandlerretryadvice.html

使用RequestHandlerRetryAdvice重试Web服务操作相关推荐

  1. JAX-WS Web 服务开发调用和数据传输分析

    一. 开发服务 新建maven的web项目就可以了, 1.新建一个web服务 2.服务名称定义 3.更改配置 4.默认建好的服务文件 5.增加一个add的服务 import javax.jws.Web ...

  2. jboss4 java_JBoss核心Java Web服务

    jboss4 java 这篇博客文章涉及Web服务. 好吧,更确切地说,它处理JBoss上的"普通" java Web服务. 这意味着我们将创建一个没有任何其他框架(例如CXF,A ...

  3. ruby和python_Ruby,Python和Java中的Web服务

    ruby和python 今天,我不得不准备一些示例来说明Web服务是可互操作的. 因此,我已经使用Metro使用Java创建了一个简单的Web服务,并在Tomcat上启动了它. 然后尝试使用Pytho ...

  4. JBoss核心Java Web服务

    这篇博客文章涉及Web服务. 好吧,更确切地说,它处理JBoss上的"普通" java Web服务. 这意味着我们将创建一个没有任何其他框架(如CXF,Axis等)的Web服务. ...

  5. Ruby,Python和Java中的Web服务

    今天,我不得不准备一些示例来说明Web服务是可互操作的. 因此,我已经使用Metro使用Java创建了一个简单的Web服务,并在Tomcat上启动了它. 然后尝试使用Python和Ruby消耗它们. ...

  6. web集成axis2_AXIS2 Web服务教程

    web集成axis2 Welcome to Apache Axis2 Tutorial. Recently I was trying to upgrade my Apache Axis2 skills ...

  7. 结合使用Ajax和Web服务

    什么是Web服务? Web服务是使用万维网公开应用程序功能的一种方式. 它通过使用开放协议来做到这一点,因此任何可以访问Web的使用应用程序也可以访问Web服务. 加入My developerWork ...

  8. 27、用户操作srv、web服务实现

    目录 一.快速启动userop_srv 1 - 快速生成项目 2 - 表结构设计 3 - nacos与yaml配置 4 - proto接口定义 5 - 启动userop_srv服务 二.service ...

  9. QT+高德地图Web服务API开发—静态地图开发Demo。QT组件提升、QT鼠标事件处理、Qt图片显示与移动、QT网络操作

    说明 在本次项目中,我们使用QT开发框架,高德地图Web服务地图API,完成一个项目Demo,进行一次对QT.对编程的学习. 本系类文章所包含内容包括: 1.QT组件提升 2.QT鼠标事件处理 3.Q ...

最新文章

  1. HTML的标签描述21
  2. oracle 实现HA,oracle RAC的客户端HA配置
  3. 51Nod 1453 抽彩球
  4. win7 telnet命令无法使用
  5. 信息系统项目管理师考试时间安排
  6. 【在路上5】实时计算助力派件管控
  7. 数据库PowerDesigner创建图表(模块表分类)
  8. 消息队列之事务消息,RocketMQ 和 Kafka是如何做的?
  9. HDU - 4746预处理莫比乌斯反演
  10. 下c语言实现wc_用 Python 实现词云可视化
  11. dva处理_dva中使用store管理数据的异步问题
  12. 【单片机基础】(四)单片机的引脚功能
  13. vue时钟+vue旋转特效
  14. 基于java的KTV点歌选歌系统
  15. 用foobar,ape转mp3
  16. 初等数论及python应用
  17. 揭秘中国球员十大豪宅
  18. python实现排序算法lowb三人组之选择排序
  19. 增量式编码器与螺旋微动机构的数显电路
  20. 大学计算机教程内容,大学计算机基础教程(教程).ppt

热门文章

  1. 微信消息提醒与消息数字提示之BadgeView
  2. nginx的日志文件配置
  3. mybatis_user_guide(4) Mapper XML 文件
  4. 如何用css3实现简单旋转的风车
  5. Servlet其他关联类---ServletContext类
  6. drools 规则流_约束流–没有Drools规则语言的现代Java约束
  7. jdbc如何写csv文件_Java:将JDBC结果集作为CSV流化
  8. 精简jdk包_具有JDK 12精简数字格式的自定义精简数字模式
  9. jshell_五分钟的JShell
  10. spark在服务器运行示例_创建示例HTTPS服务器以获取乐趣和收益