SqsListener字符串索引超出范围问题

时间:2018-09-13 18:37:46

标签: spring amazon-web-services spring-boot spring-cloud amazon-sqs

当尝试使用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-messaging模块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);
    }
}

以前有人看过吗?如果可以的话,有没有办法解决这个问题?

P.S:由于我不太在乎消息属性,因此我不介意它们是否被完全忽略。

谢谢。

1 个答案:

答案 0 :(得分:0)

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

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

根据AWS JAVA SDK中的文档,它说明了getDataType()函数的工作方式(请参见this link)。根据文档,它将返回以下值之一。

  • 字符串

  • 编号

  • 二进制

  

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

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

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

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

String numberType = value.getDataType();