I'm using Camel REST with Camel servlet handling the REST transport and want to change the way headers from the exchange are processed in HTTP requests and responses. I'm using Spring XML to configure my application. Here's the relevant configuration I'm using:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<!-- Custom Camel Configuration //////////////////////////////////////////////////////////////////////////////// -->
<bean id="myHttpBinding" class="com.example.MyHttpBinding"/>
<bean id="servlet" class="org.apache.camel.component.servlet.ServletComponent">
<property name="httpBinding" ref="myHttpBinding"/>
</bean>
<!-- Routes //////////////////////////////////////////////////////////////////////////////////////////////////// -->
<camel:camelContext id="myCamelContext">
<camel:contextScan/>
<camel:restConfiguration component="servlet" enableCORS="true" bindingMode="json" skipBindingOnErrorCode="false">
<camel:corsHeaders key="Access-Control-Allow-Methods" value="PATCH, PUT, POST, DELETE, GET, OPTIONS, HEAD"/>
<camel:corsHeaders key="Access-Control-Allow-Origin" value="*"/>
<camel:corsHeaders key="Access-Control-Allow-Headers" value="*"/>
</camel:restConfiguration>
</camel:camelContext>
</beans>
When the routes are created, I see that the endpoints are configured with MyHttpBinding
set. However, incoming requests are still using ServletRestHttpBinding
. This is because when Camel creates the consumer, it executes this block of code:
if (!map.containsKey("httpBinding")) {
// use the rest binding, if not using a custom http binding
HttpBinding binding = new ServletRestHttpBinding();
binding.setHeaderFilterStrategy(endpoint.getHeaderFilterStrategy());
binding.setTransferException(endpoint.isTransferException());
binding.setEagerCheckContentAvailable(endpoint.isEagerCheckContentAvailable());
endpoint.setHttpBinding(binding);
}
How can I set the HTTP binding in a way that Camel will respect it?
Because Camel ultimately looks for the httpBinding
property on the endpoint to determine the binding strategy to use, the REST component has to be configured to add that property to the endpoint like so:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<!-- Custom Camel Configuration //////////////////////////////////////////////////////////////////////////////// -->
<bean id="myHttpBinding" class="com.example.MyHttpBinding"/>
<!-- Routes //////////////////////////////////////////////////////////////////////////////////////////////////// -->
<camel:camelContext id="myCamelContext">
<camel:contextScan/>
<camel:restConfiguration component="servlet" enableCORS="true" bindingMode="json" skipBindingOnErrorCode="false">
<camel:endpointProperty key="httpBinding" value="myHttpBinding"/>
<camel:corsHeaders key="Access-Control-Allow-Methods" value="PATCH, PUT, POST, DELETE, GET, OPTIONS, HEAD"/>
<camel:corsHeaders key="Access-Control-Allow-Origin" value="*"/>
<camel:corsHeaders key="Access-Control-Allow-Headers" value="*"/>
</camel:restConfiguration>
</camel:camelContext>
</beans>
Note that I removed the custom servlet component because it wasn't necessary.