SqsListener 字符串索引越界问题



我在尝试使用Spring Cloud模块中的@SQSListener注释时遇到了一个非常奇怪的问题。 这是我的侦听器方法:

@SqsListener(value = "myproject-dev-au-error-queue")
public void listenPhoenix(String message) throws IOException {
logger.info(message);
}

但是,一旦我运行该项目,它就会开始从队列中读取消息并失败并显示以下错误:

Exception in thread "simpleMessageListenerContainer-4" Exception in thread "simpleMessageListenerContainer-6" Exception in thread "simpleMessageListenerContainer-9" Exception in thread "simpleMessageListenerContainer-10" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(String.java:1931)
at org.springframework.cloud.aws.messaging.core.QueueMessageUtils.getNumberValue(QueueMessageUtils.java:93)
at org.springframework.cloud.aws.messaging.core.QueueMessageUtils.getMessageAttributesAsMessageHeaders(QueueMessageUtils.java:80)
at org.springframework.cloud.aws.messaging.core.QueueMessageUtils.createMessage(QueueMessageUtils.java:56)
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer$MessageExecutor.getMessageForExecution(SimpleMessageListenerContainer.java:375)
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer$MessageExecutor.run(SimpleMessageListenerContainer.java:336)
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer$SignalExecutingRunnable.run(SimpleMessageListenerContainer.java:392)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

有问题的部分在 spring-cloud-aws 消息传递模块中QueueMessageUtilsnumberType变量赋值:

private static Object getNumberValue(MessageAttributeValue value) {
String numberType = value.getDataType().substring("Number".length() + 1);
try {
Class<? extends Number> numberTypeClass = Class.forName(numberType).asSubclass(Number.class);
return NumberUtils.parseNumber(value.getStringValue(), numberTypeClass);
} catch (ClassNotFoundException var3) {
throw new MessagingException(String.format("Message attribute with value '%s' and data type '%s' could not be converted into a Number because target class was not found.", value.getStringValue(), value.getDataType()), var3);
}
}

以前有没有人见过这个,如果有,有没有办法解决这个问题?

PS:由于我并不真正关心消息属性,因此我不介意完全忽略它们。

提前谢谢。

给定代码中的异常从下一行引发。

String numberType = value.getDataType().substring("Number".length() + 1);

根据 AWS JAVA SDK 中的文档,它解释了getDataType()函数的工作原理(请参阅此链接(。根据文档,它将返回以下值之一。

  • 字符串

  • 二元的

Amazon SQS 支持以下逻辑数据类型:字符串、数字、 和二进制。对于"数字"数据类型,必须使用"字符串值"。

现在,当您调用value.getDataType()时,它将返回上述值之一。假设它是"Number"的,你试图从索引 6 开始获取它的substring(其中"Number".length() + 1 = 6(

但是value.getDataType()返回的字符串中没有这样的索引。因此,它将引发java.lang.StringIndexOutOfBoundsException异常。

作为解决方案,您可以简单地使用以下内容,而不是获取它的子字符串。

String numberType = value.getDataType();

我也遇到了同样的问题,当使用SQS 扩展库发布消息时,它会自动添加一个属性以及消息SQSLargePayloadSize以及导致问题的数据类型Number的消息。 通过将依赖项从

implementation group: 'org.springframework.cloud', name: 'spring-cloud-aws-messaging', version: '2.2.6.RELEASE'

到任何最新版本的 awSpringSpring-cloud-aws-messaging

implementation group: 'io.awspring.cloud', name: 'spring-cloud-aws-messaging', version: '2.4.1'

确保必须从io.awspring.cloud导入所有包

最新更新