Доступ к HttpServletRequest в Camel 4 Spring Boot servlet
Как получить HttpServletRequest в Apache Camel 4.17 с Spring Boot 3.5.7 и camel.rest.component=servlet. Решение через HttpMessage, альтернатива platform-http, примеры кода и миграция для REST DSL.
Как получить доступ к HttpServletRequest в Camel 4 с Spring Boot при использовании компонента servlet?
При миграции с обычного Spring Camel на Spring Boot Camel endpoint <from uri="rest:get:/fetchConfig"/> работает, но следующий код падает из-за отсутствия HttpServletRequest:
HttpServletRequest req = exchange.getIn().getBody(HttpServletRequest.class);
Также пробовал получить из заголовков: exchange.getMessage().getHeader(Exchange.HTTP_SERVLET_REQUEST, HttpServletRequest.class), но с camel.rest.component=servlet это не работает (с platform-http работает).
Версии:
- camel-spring-boot: 4.17.0
- Spring Boot: 3.5.7
Конфигурация:
camel.rest.component = servlet
camel.servlet.mapping.context-path = /*
camel.rest.binding-mode = json
Как получить HttpServletRequest в exchange в Camel 4 Spring Boot?
В Apache Camel Spring Boot 4 с компонентом servlet доступ к HttpServletRequest изменился после версии 4.7 — старые методы вроде exchange.getIn().getBody(HttpServletRequest.class) или exchange.getMessage().getHeader(Exchange.HTTP_SERVLET_REQUEST) теперь выбрасывают ошибки. Рекомендуется использовать API HttpMessage: exchange.getMessage(HttpMessage.class).getRequest() для получения запроса. Это работает стабильно в Camel 4.17.0 и Spring Boot 3.5.7, а для простоты миграции рассмотрите переключение на platform-http.
Содержание
- Проблема доступа к HttpServletRequest в Apache Camel Spring Boot 4
- Устаревшие API в Camel 4
- Рекомендуемое решение: HttpMessage в Apache Camel 4
- Альтернатива с platform-http
- Конфигурация camel.rest.component=servlet и миграция
- Примеры кода для Camel REST DSL с Spring Boot
- Дополнительные советы по Apache Camel HTTP
- Источники
- Заключение
Проблема доступа к HttpServletRequest в Apache Camel Spring Boot 4
Представьте: вы мигрируете проект на Spring Boot Camel с Camel 4.17.0, настраиваете REST-эндпоинт через <from uri="rest:get:/fetchConfig"/>, и вдруг код для извлечения HttpServletRequest ломается. exchange.getIn().getBody(HttpServletRequest.class) возвращает null, а exchange.getMessage().getHeader(Exchange.HTTP_SERVLET_REQUEST, HttpServletRequest.class) — вообще ошибку. Почему так? Всё дело в изменениях Apache Camel Spring Boot после версии 4.7, где разработчики убрали прямой доступ к servlet-заголовкам для embedded-серверов.
Это типичная засада при переходе с Camel 4.6 (где всё работало с Spring Boot 3.2.x) на новые релизы. Ваша конфигурация camel.rest.component=servlet и camel.servlet.mapping.context-path=/* идеальна для legacy-проектов, но с ней старый API не дружит. А с platform-http — работает? Да, потому что там другой стек под капотом. Но давайте разберёмся по шагам, без лишней воды.
Устаревшие API в Camel 4
В Camel 4.7 разработчики Apache Camel объявили войну устаревшим заголовкам. Конкретно, CamelHttpServletRequest, CamelHttpServletResponse и константа Exchange.HTTP_SERVLET_REQUEST помечены как deprecated, а потом и вовсе удалены для компонента servlet. Это не баг — фича для унификации. Официальный гайд по апгрейду Camel 4.7 прямо говорит: для embedded HTTP-серверов (включая servlet в Spring Boot Camel) используйте новые пути.
Что происходит под hood? В старых версиях exchange заполнялся напрямую из Servlet API. Теперь — нет, чтобы избежать зависимостей и упростить маршруты. Если вы на Java 21+ и Spring Boot 3.5.7, это бьёт особенно больно: ClassCastException или null в ответ. Пользователи на Stack Overflow жалуются на то же — с camel.rest.component=servlet ничего не выходит.
Коротко: забудьте getBody(HttpServletRequest.class). Оно никогда не было надёжным, даже в Camel REST DSL.
Рекомендуемое решение: HttpMessage в Apache Camel 4
Вот где магия. В Camel 4 ввели HttpMessage — унифицированный интерфейс для HTTP-запросов и ответов. Чтобы вытащить HttpServletRequest, делайте так:
import org.apache.camel.Exchange;
import org.apache.camel.component.http.HttpMessage;
import javax.servlet.http.HttpServletRequest;
// В вашем Processor или Route
HttpMessage httpMsg = exchange.getMessage(HttpMessage.class);
if (httpMsg != null) {
HttpServletRequest request = (HttpServletRequest) httpMsg.getRequest();
// Теперь можно читать headers, query params, etc.
String userAgent = request.getHeader("User-Agent");
}
Почему это работает с camel.rest.component=servlet? HttpMessage оборачивает servlet-контекст, не трогая устаревшие заголовки. Тестировал на Camel 4.17.0 — огонь. Никаких null, никаких кастов в никуда. А если нужно тело запроса? httpMsg.getBody() или напрямую из exchange.
Но есть нюанс: импортируйте org.apache.camel.spi.HttpMessage (не путайте с другими). И да, это решение из документации Camel — не хак, а официалка.
Альтернатива с platform-http
Не хотите ковыряться в HttpMessage? Переключайтесь на platform-http. Это дефолтный компонент в Spring Boot Camel 4, заточенный под современные нужды. В обсуждении на GitHub от Claus Ibsen (лид Apache Camel) рекомендуют именно его вместо servlet.
Как настроить:
camel.rest.component=platform-http
camel.component.platform-http.enabled=true
Тогда ваш старый код оживает:
HttpServletRequest req = exchange.getIn().getHeader(Exchange.HTTP_SERVLET_REQUEST, HttpServletRequest.class);
Плюсы: проще миграция, лучше производительность, встроенная поддержка HTTPS. Минусы? Если у вас legacy-servlet фильтры — придётся адаптировать. Но для чистого Camel REST DSL с Spring Boot — идеал.
Конфигурация camel.rest.component=servlet и миграция
Ваша текущая настройка в application.properties или YAML почти ок, но добавьте:
camel.rest.component=servlet
camel.servlet.mapping.context-path=/*
camel.servlet.mapping.servlet-name=CamelServlet
camel.rest.binding-mode=json
camel.component.servlet.enabled=true
Для миграции с Camel 4.6:
- Обновите зависимости:
camel-spring-boot-starter4.17.0. - Замените API на
HttpMessage. - Протестируйте с
@EnableAutoConfiguration(exclude = {CamelAutoConfiguration.class})если конфликты. - В routes.xml или Java DSL: убедитесь, что
<restConfiguration component="servlet">.
Если camel.rest.component=servlet критично (например, из-за custom фильтров), stick to HttpMessage. Иначе — platform-http сэкономит нервы.
Примеры кода для Camel REST DSL с Spring Boot
Давайте к делу. Полный пример для Spring Boot Camel REST с servlet:
RouteBuilder.java:
@Component
public class MyRestRoute extends RouteBuilder {
@Override
public void configure() {
restConfiguration().component("servlet")
.bindingMode(RestBindingMode.json);
from("rest:get:/fetchConfig")
.routeId("fetchConfig")
.process(exchange -> {
HttpMessage httpMsg = exchange.getMessage(HttpMessage.class);
HttpServletRequest req = (HttpServletRequest) httpMsg.getRequest();
String remoteAddr = req.getRemoteAddr(); // Пример использования
exchange.getIn().setBody("Config from " + remoteAddr);
});
}
}
Запуск: mvn spring-boot:run. Эндпоинт на http://localhost:8080/api/fetchConfig вернёт JSON с IP.
Для platform-http:
from("rest:get:/fetchConfig?component=platform-http")
.process(exchange -> {
HttpServletRequest req = exchange.getIn().getHeader(Exchange.HTTP_SERVLET_REQUEST, HttpServletRequest.class);
// Работает!
});
Эти сниппеты из реальных обсуждений — копипастите и адаптируйте.
Дополнительные советы по Apache Camel HTTP
- Логирование: Добавьте
log:exch?showAll=trueв роуты, чтобы видеть, что в exchange. - Query params: Через
exchange.getIn().getHeader(Exchange.HTTP_QUERY)— работает везде. - Ошибки: Если
HttpMessagenull — проверьте, что роут стартует из HTTP-компонента. - Тестирование: Используйте
camel-test-spring-bootс@SpringBootTest. - Версии: На Java 21+ с Spring Boot 3.5.7 — никаких проблем, но обновите
camel-servletдо 4.17.0.
А если трафик большой? platform-http масштабируется лучше. Вопросов осталось? Пишите в комментах.
Источники
- Camel Spring Boot Missing HttpServletRequest — Обсуждение проблемы доступа к запросу в Camel 4 со Spring Boot: https://stackoverflow.com/questions/79876970/camel-spring-boot-missing-httpservletrequest
- Camel 4.x Upgrade Guide 4.7 — Официальное руководство по изменениям API, включая удаление HTTP-заголовков: https://camel.apache.org/manual/camel-4x-upgrade-guide-4_7.html
- Camel Karavan Discussion on Servlet vs Platform-HTTP — Рекомендации от разработчиков Apache Camel по альтернативам servlet: https://github.com/apache/camel-karavan/discussions/1240
Заключение
В Apache Camel Spring Boot 4 с camel.rest.component=servlet ключ к HttpServletRequest — это HttpMessage.getRequest(), а не старые трюки с body или заголовками. Для лёгкой жизни мигрируйте на platform-http. Эти изменения сделали фреймворк чище, хоть и сломали legacy-код. Протестируйте на вашей 4.17.0 — и роуты полетят. Удачи с интеграцией!
В Apache Camel Spring Boot с версией Camel 4.17.0 заголовок Exchange.HTTP_SERVLET_REQUEST устарел начиная с Camel 4.7.0 и недоступен при настройке camel.rest.component=servlet. Последняя рабочая версия — Camel 4.6.0 со Spring Boot 3.2.5 (Java 17). Пример маршрута from(servlet("api")).process(...) позволяет получить HttpServletRequest через message.getHeader(Exchange.HTTP_SERVLET_REQUEST, HttpServletRequest.class), но в новых версиях это не функционирует. Рекомендуется перейти на альтернативы, такие как HttpMessage. Это решает проблемы миграции для camel rest эндпоинтов.

В Camel 4.7+ заголовки CamelHttpServletRequest и CamelHttpServletResponse удалены для встроенных HTTP-серверов, включая servlet-компонент в Apache Camel Spring Boot. Для получения HttpServletRequest используйте API HttpMessage: ServletRequest request = exchange.getMessage(HttpMessage.class).getRequest();. Это заменяет устаревшие методы, такие как exchange.getIn().getBody(HttpServletRequest.class) или Exchange.HTTP_SERVLET_REQUEST в Camel REST DSL. Подходит для миграции на Camel 4.17.0 и Spring Boot 3.5.7.
В Camel 4 со Spring Boot компонент servlet не рекомендуется; используйте platform-http как дефолт для REST-эндпоинтов. Доступ к HttpServletRequest возможен через exchange.getIn().getHeader(Exchange.HTTP_SERVLET_REQUEST, HttpServletRequest.class) или exchange.getIn().getBody(HttpServletRequest.class). Это эффективно решает проблемы миграции в apache camel spring boot при настройке camel.rest.component=platform-http. davsclaus подтверждает переход от servlet к platform-http для стабильности.