Http Outbound Gateway动态填充URL报错问题求助
Let's tackle both of your errors one by one, with clear fixes you can apply immediately:
1. Fixing "Could not resolve placeholder 'UrlVariable' in string value"
Root Cause
You confused Spring property placeholders ( ${...} ) with Spring Integration URI variables ( {...} ). The ${UrlVariable} syntax tells Spring to look for a static property named UrlVariable in your configuration files (like application.properties), but you actually want to dynamically populate the URL from a message header.
Correct Configuration
Update your <http:outbound-gateway> to use URI variable syntax instead of property placeholders, and align the variable name with your header:
<http:outbound-gateway mapped-request-headers="Accept*, Content-Type, X-*, HTTP_REQUEST_HEADERS" request-channel="create_order_outbound_gateway_with_json_POST" reply-channel="print_payload" url="{postURL}" <!-- Use URI variable syntax here --> http-method="POST" expected-response-type="java.lang.String" charset="UTF-8" request-factory="httpRequestFactory"> <http:uri-variable name="postURL" expression="headers['postURL']"/> <!-- Match the variable name in url --> </http:outbound-gateway>
This tells Spring Integration to replace {postURL} with the value of the postURL header from your message, instead of trying to resolve it as a static configuration property.
2. Fixing "Invalid use of BasicClientConnManager: connection still allocated"
Root Cause
BasicClientConnectionManager is a single-threaded connection manager—it only allows one active connection at a time. If you have concurrent requests or connections aren't properly released (e.g., due to unhandled exceptions), you'll hit this error.
Correct Configuration
Replace BasicClientConnectionManager with PoolingHttpClientConnectionManager, which supports concurrent connections. Here's how to configure it in XML:
First, define the pooling connection manager and HTTP client:
<bean id="poolingConnManager" class="org.apache.http.impl.conn.PoolingHttpClientConnectionManager"> <property name="maxTotal" value="100"/> <!-- Adjust based on your concurrency needs --> <property name="defaultMaxPerRoute" value="20"/> </bean> <bean id="httpClient" class="org.apache.http.impl.client.HttpClientBuilder" factory-method="create"> <property name="connectionManager" ref="poolingConnManager"/> </bean>
Then update your httpRequestFactory to use this pooled client:
<bean id="httpRequestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory"> <constructor-arg ref="httpClient"/> <!-- Optional: Set connection/read timeouts --> <property name="connectTimeout" value="5000"/> <property name="readTimeout" value="10000"/> </bean>
This setup allows multiple concurrent connections and properly manages connection lifecycle, eliminating the "connection still allocated" error.
Full Modified Configuration Snippet
Putting it all together, your relevant config should look like this:
<int:header-enricher input-channel="jmsInboundChannel_POST" output-channel="outbound_gateway_channel_POST"> <int:header name="postURL" expression="payload.getUrl()"/> <int:header name="Accept-Language" value="en_GB"/> <int:header name="X-Source-CountryCode" value="GB"/> <int:header name="X-Source-Operator" value="Enterprise"/> <int:header name="X-Source-Division" value="OrderManagement"/> <int:header name="X-Source-System" value="${sapwebservices.http.header.source.system}"/> <int:header name="X-Source-Timestamp" expression="new java.text.SimpleDateFormat('yyyy-MM-dd HH:mm:ss').format(new java.util.Date())"/> <int:header name="Accept" value="application/json"/> <int:header name="Content-Type" value="application/json;charset=UTF-8"/> </int:header-enricher> <int:object-to-json-transformer input-channel="outbound_gateway_channel_POST" output-channel="create_order_outbound_gateway_with_json_POST" object-mapper="nonNullObjectMapper"/> <!-- New Pooled Connection Manager Setup --> <bean id="poolingConnManager" class="org.apache.http.impl.conn.PoolingHttpClientConnectionManager"> <property name="maxTotal" value="100"/> <property name="defaultMaxPerRoute" value="20"/> </bean> <bean id="httpClient" class="org.apache.http.impl.client.HttpClientBuilder" factory-method="create"> <property name="connectionManager" ref="poolingConnManager"/> </bean> <bean id="httpRequestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory"> <constructor-arg ref="httpClient"/> <property name="connectTimeout" value="5000"/> <property name="readTimeout" value="10000"/> </bean> <!-- Fixed Outbound Gateway --> <http:outbound-gateway mapped-request-headers="Accept*, Content-Type, X-*, HTTP_REQUEST_HEADERS" request-channel="create_order_outbound_gateway_with_json_POST" reply-channel="print_payload" url="{postURL}" http-method="POST" expected-response-type="java.lang.String" charset="UTF-8" request-factory="httpRequestFactory"> <http:uri-variable name="postURL" expression="headers['postURL']"/> </http:outbound-gateway>
内容的提问来源于stack exchange,提问作者rowen

