SqsListener Строковый индекс выходит за границы - PullRequest
0 голосов
/ 13 сентября 2018

Я столкнулся с действительно странной проблемой при попытке использовать аннотацию @SQSListener из модуля Spring Cloud. Вот мой метод слушателя:

@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 QueueMessageUtils class numberType назначение переменной:

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);
    }
}

Кто-нибудь видел это раньше, и если да, есть ли способ это исправить?

П.С .: Поскольку меня не интересуют атрибуты сообщений, я бы не стал возражать, если бы они были полностью проигнорированы.

Заранее спасибо.

1 Ответ

0 голосов
/ 14 сентября 2018

Исключение в данном коде выдается из следующей строки.

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

Согласно документации в AWS JAVA SDK объясняется, как работает функция getDataType() (см. эту ссылку ). Согласно документации, он вернет одно из следующих значений.

  • Строка

  • номер

  • Binary

Amazon SQS поддерживает следующие логические типы данных: String, Number, и бинарный. Для типа данных Number необходимо использовать StringValue.

Теперь, когда вы позвоните value.getDataType(), он вернет одно из вышеуказанных значений. Предполагая, что это "Number", вы пытаетесь получить его substring, начиная с индекса 6 (где "Number".length() + 1 = 6)

Но в строке, возвращаемой value.getDataType(), такого индекса нет. Следовательно, он выдаст исключение java.lang.StringIndexOutOfBoundsException.

В качестве решения для этого вы можете просто использовать следующее вместо получения его подстроки.

String numberType = value.getDataType();
...