【问题标题】:SqsListener String index out of bounds issueSqsListener 字符串索引越界问题
【发布时间】:2019-02-18 13:17:47
【问题描述】:

我在尝试使用 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:由于我并不真正关心消息属性,如果它们被完全忽略,我不会介意。

提前致谢。

【问题讨论】:

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


    【解决方案1】:

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

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

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

    • 字符串

    • 编号

    • 二进制

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

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

    但是value.getDataType()返回的String中没有这样的索引。因此,它会抛出一个java.lang.StringIndexOutOfBoundsException 异常。

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

    String numberType = value.getDataType();
    

    【讨论】:

    • 是的,问题是这个方法是Spring Cloud消息模块的一部分。我在他们的 github 存储库中提出了一个问题:github.com/spring-cloud/spring-cloud-aws/issues/374
    • @DannyPetrunov 请随时向我们发布任何解决方案。我曾经使用 AWS Java SDK 实现并使用了这种精确的方法。它对我有用。获取它的子字符串并尝试解决它,似乎不是一个好习惯imo
    猜你喜欢
    • 1970-01-01
    • 2012-12-01
    • 1970-01-01
    • 2011-12-13
    • 1970-01-01
    • 2019-08-01
    • 2016-06-10
    • 2013-12-08
    • 2014-10-16
    相关资源
    最近更新 更多