#spring-boot #apache-camel
Вопрос:
После вызова rest я пытаюсь настроить маршрут верблюда, чтобы вернуть данные и записать их в файл cvs. Проблема в том, что я могу заставить его выполнить только одно из двух.
from("direct:select")
.setBody(constant("select * from animal")).to("jdbc:dataSource").marshal().csv()
.to("file:///tmp?fileName=MY_TEST_FILE.csv");
В текущей версии он записывает в файл правильно, но остальной ответ-это просто набор цифр. Хотя, если я изменю порядок функций, таких как:
from("direct:select")
.setBody(constant("select * from animal"))
.to("file:///tmp?fileName=MY_TEST_FILE.csv").marshal().csv().to("jdbc:dataSource");
Я получаю правильный ответ rest, но в файле я получаю:
select * from applicant
Есть ли способ сделать и то, и другое с одного верблюжьего маршрута?
Ответ №1:
Camel просто выполняет инструкции по маршрутизации/преобразованию в том порядке, в котором вы их определяете.
Ваша первая попытка имеет некоторый смысл: вы запускаете запрос select, получаете список строк из вызова JDBC, конвертируете его в CSV, затем записываете в файл и возвращаете в качестве ответа на свой маршрут. Эту последнюю часть важно понять: ответ с вашего маршрута будет таким, каким будет ваше тело обмена в конце (синхронной) обработки. Учитывая, что вы недовольны этой первой попыткой, я пойду и предположу, что формат CSV-это не то, что вы собираетесь вернуть в качестве ответа.
Теперь, глядя на вашу вторую попытку, вы говорите, что она возвращает ожидаемый ответ, но это меня удивляет: вы пытаетесь преобразовать буквальную строку «select * from animal» в CSV, что вызывает исключение на моем конце:
орг.апач.верблюд.NoTypeConversionAvailableException: Конвертер типов не доступен для преобразования из типа: java.lang.Строка требуемого типа: java.util.Список со значением выберите * из животного
Теперь , если вы удалите .marshal().csv()
его, маршрут будет работать. Он записывает «выбрать * из животного» в файл, как вы заметили (но это именно то, что предписывает маршрут), и в качестве ответа возвращает содержимое тела обмена в конце маршрута, что означает List
результат вызова JDBC. Таким образом, я сделаю еще одно предположение, что этот список на самом деле является тем, что вы собираетесь вернуть (вы, вероятно, хотите вернуть JSON, поэтому List
действительно подходит для бесшовного преобразования JSON).
Имея все это в виду, давайте попробуем найти для вас маршрут, который делает то, что вы хотите. Однако мы немного уперлись в стену с вашим требованием «делать и то, и другое с одного верблюжьего маршрута». Будем надеяться, что вы не хотели исключать использование подмаршрутов, связанных direct:
конечными точками (я не вижу веских причин, по которым вы хотели бы этого избежать).
Вот первое решение, которое делает все синхронно (вызов JDBC запись в файл, выполняемые исходным потоком):
from("direct:select")
.setBody(constant("select * from animal"))
.to("jdbc:dataSource")
.enrich("direct:file", new UseOriginalAggregationStrategy());
from("direct:file")
.marshal().csv()
.to("file:///tmp?fileName=MY_TEST_FILE.csv");
Более подробную информацию смотрите в разделе Camel Enrich EIP.
И вот один, который будет записывать в файл асинхронно (т. Е. в отдельном потоке), что означает, что ваш вызов REST должен быть немного быстрее для ответа:
from("direct:select")
.setBody(constant("select * from animal"))
.to("jdbc:dataSource")
.wireTap("direct:file");
from("direct:file")
.marshal().csv()
.to("file:///tmp?fileName=MY_TEST_FILE.csv");
Более подробную информацию смотрите в разделе EIP для подключения провода Camel.