INT-3055: HTTP Outbound uri-variables-expression
JIRA: https://jira.springsource.org/browse/INT-3055 * Add to HTTP Outbound Endpoint `uri-variables-expression` * Add mutually exclusive check for `uri-variables-expression` with `<uri-variable>` * Tests and Docs INT-3055: Fixes * `ExpressionEvalMap` now can apply `Map<String, Object>`, but the value must have a `String` or `Expression` type. Polishing INT-3055 Doc Polishing
This commit is contained in:
committed by
Gary Russell
parent
8ab65c6dd3
commit
a7cabc53b0
@@ -23,10 +23,13 @@ import java.util.Set;
|
||||
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.common.LiteralExpression;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* An immutable {@link AbstractMap} implementation that wraps a Map<String, Expression>
|
||||
* An immutable {@link AbstractMap} implementation that wraps a {@code Map<String, Object>},
|
||||
* where values must be instances of {@link String} or {@link Expression},
|
||||
* and evaluates an {@code expression} for the provided {@code key} from the underlying
|
||||
* {@code original} Map.
|
||||
* </p>
|
||||
@@ -38,16 +41,18 @@ import org.springframework.expression.Expression;
|
||||
* <p>
|
||||
* A {@link ExpressionEvalMapBuilder} must be used to instantiate this class
|
||||
* via its {@link #from(Map)} method:
|
||||
* <pre class="code">
|
||||
* {@code
|
||||
* ExpressionEvalMap evalMap = ExpressionEvalMap
|
||||
* .from(expressions)
|
||||
.usingCallback(new EvaluationCallback() {
|
||||
Object evaluate(Expression expression) {
|
||||
// return some expression evaluation
|
||||
}
|
||||
})
|
||||
.build();
|
||||
* }
|
||||
*ExpressionEvalMap evalMap = ExpressionEvalMap
|
||||
* .from(expressions)
|
||||
* .usingCallback(new EvaluationCallback() {
|
||||
* Object evaluate(Expression expression) {
|
||||
* // return some expression evaluation
|
||||
* }
|
||||
* })
|
||||
* .build();
|
||||
*}
|
||||
* </pre>
|
||||
* </p>
|
||||
* <p>
|
||||
* Thread-safety depends on the original underlying Map.
|
||||
@@ -68,11 +73,11 @@ public final class ExpressionEvalMap extends AbstractMap<String, Object> {
|
||||
|
||||
};
|
||||
|
||||
private final Map<String, Expression> original;
|
||||
private final Map<String, ?> original;
|
||||
|
||||
private final EvaluationCallback evaluationCallback;
|
||||
|
||||
private ExpressionEvalMap(Map<String, Expression> original, EvaluationCallback evaluationCallback) {
|
||||
private ExpressionEvalMap(Map<String, ?> original, EvaluationCallback evaluationCallback) {
|
||||
this.original = original;
|
||||
this.evaluationCallback = evaluationCallback;
|
||||
}
|
||||
@@ -83,8 +88,20 @@ public final class ExpressionEvalMap extends AbstractMap<String, Object> {
|
||||
*/
|
||||
@Override
|
||||
public Object get(Object key) {
|
||||
Expression expression = original.get(key);
|
||||
if (expression != null) {
|
||||
Object value = original.get(key);
|
||||
if (value != null) {
|
||||
Expression expression;
|
||||
if (value instanceof Expression) {
|
||||
expression = (Expression) value;
|
||||
}
|
||||
else if (value instanceof String) {
|
||||
expression = new LiteralExpression((String) value);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Values must be "
|
||||
+ "'java.lang.String' or 'org.springframework.expression.Expression'; the value type for key "
|
||||
+ key + " is : " + value.getClass());
|
||||
}
|
||||
return this.evaluationCallback.evaluate(expression);
|
||||
}
|
||||
return null;
|
||||
@@ -136,7 +153,7 @@ public final class ExpressionEvalMap extends AbstractMap<String, Object> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends String, ? extends Object> m) {
|
||||
public void putAll(Map<? extends String, ?> m) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@@ -155,7 +172,13 @@ public final class ExpressionEvalMap extends AbstractMap<String, Object> {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public static ExpressionEvalMapBuilder from(Map<String, Expression> expressions) {
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.original.toString();
|
||||
}
|
||||
|
||||
public static ExpressionEvalMapBuilder from(Map<String, ?> expressions) {
|
||||
Assert.notNull(expressions, "'expressions' must not be null.");
|
||||
return new ExpressionEvalMapBuilder(expressions);
|
||||
}
|
||||
|
||||
@@ -205,7 +228,7 @@ public final class ExpressionEvalMap extends AbstractMap<String, Object> {
|
||||
*/
|
||||
public static final class ExpressionEvalMapBuilder {
|
||||
|
||||
private final Map<String, Expression> expressions;
|
||||
private final Map<String, ?> expressions;
|
||||
|
||||
private EvaluationCallback evaluationCallback;
|
||||
|
||||
@@ -219,7 +242,7 @@ public final class ExpressionEvalMap extends AbstractMap<String, Object> {
|
||||
|
||||
private final ExpressionEvalMapFinalBuilder finalBuilder = new ExpressionEvalMapFinalBuilderImpl();
|
||||
|
||||
private ExpressionEvalMapBuilder(Map<String, Expression> expressions) {
|
||||
private ExpressionEvalMapBuilder(Map<String, ?> expressions) {
|
||||
this.expressions = expressions;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,6 +34,7 @@ import org.springframework.util.xml.DomUtils;
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Mark Fisher
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
* @since 2.0.2
|
||||
*/
|
||||
abstract class HttpAdapterParsingUtils {
|
||||
@@ -52,9 +53,23 @@ abstract class HttpAdapterParsingUtils {
|
||||
}
|
||||
}
|
||||
|
||||
static void configureUriVariableExpressions(BeanDefinitionBuilder builder, Element element) {
|
||||
static void configureUriVariableExpressions(BeanDefinitionBuilder builder, ParserContext parserContext, Element element) {
|
||||
String uriVariablesExpression = element.getAttribute("uri-variables-expression");
|
||||
|
||||
List<Element> uriVariableElements = DomUtils.getChildElementsByTagName(element, "uri-variable");
|
||||
if (!CollectionUtils.isEmpty(uriVariableElements)) {
|
||||
boolean hasUriVariableExpressions = !CollectionUtils.isEmpty(uriVariableElements);
|
||||
|
||||
if (StringUtils.hasText(uriVariablesExpression)) {
|
||||
if (hasUriVariableExpressions) {
|
||||
parserContext.getReaderContext().error("'uri-variables-expression' attribute " +
|
||||
"and 'uri-variable' sub-elements are mutually exclusive.", element);
|
||||
}
|
||||
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(ExpressionFactoryBean.class)
|
||||
.addConstructorArgValue(uriVariablesExpression);
|
||||
builder.addPropertyValue("uriVariablesExpression", beanDefinitionBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
if (hasUriVariableExpressions) {
|
||||
ManagedMap<String, Object> uriVariableExpressions = new ManagedMap<String, Object>();
|
||||
for (Element uriVariableElement : uriVariableElements) {
|
||||
String name = uriVariableElement.getAttribute("name");
|
||||
|
||||
@@ -77,7 +77,7 @@ public class HttpOutboundChannelAdapterParser extends AbstractOutboundChannelAda
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "charset");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "extract-payload");
|
||||
HttpAdapterParsingUtils.setExpectedResponseOrExpression(element, parserContext, builder);
|
||||
HttpAdapterParsingUtils.configureUriVariableExpressions(builder, element);
|
||||
HttpAdapterParsingUtils.configureUriVariableExpressions(builder, parserContext, element);
|
||||
return builder.getBeanDefinition();
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ public class HttpOutboundGatewayParser extends AbstractConsumerEndpointParser {
|
||||
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "reply-timeout", "sendTimeout");
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "reply-channel", "outputChannel");
|
||||
HttpAdapterParsingUtils.configureUriVariableExpressions(builder, element);
|
||||
HttpAdapterParsingUtils.configureUriVariableExpressions(builder, parserContext, element);
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "transfer-cookies");
|
||||
return builder;
|
||||
}
|
||||
|
||||
@@ -111,6 +111,10 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
|
||||
|
||||
private volatile HeaderMapper<HttpHeaders> headerMapper = DefaultHttpHeaderMapper.outboundMapper();
|
||||
|
||||
private volatile Expression uriVariablesExpression;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a handler that will send requests to the provided URI.
|
||||
*/
|
||||
@@ -280,6 +284,15 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link Expression} to evaluate against the outbound message; the expression
|
||||
* must evaluate to a Map of URI variable expressions to evaluate against the outbound message
|
||||
* when replacing the variable placeholders in a URI template.
|
||||
*/
|
||||
public void setUriVariablesExpression(Expression uriVariablesExpression) {
|
||||
this.uriVariablesExpression = uriVariablesExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true if you wish 'Set-Cookie' headers in responses to be
|
||||
* transferred as 'Cookie' headers in subsequent interactions for
|
||||
@@ -314,6 +327,7 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
|
||||
}
|
||||
|
||||
private class ClassToStringConverter implements Converter<Class<?>, String> {
|
||||
@Override
|
||||
public String convert(Class<?> source) {
|
||||
return source.getName();
|
||||
}
|
||||
@@ -326,6 +340,7 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
|
||||
*
|
||||
*/
|
||||
private class ObjectToStringConverter implements Converter<Object, String> {
|
||||
@Override
|
||||
public String convert(Object source) {
|
||||
if (source instanceof Class) {
|
||||
return ((Class<?>) source).getName();
|
||||
@@ -351,11 +366,7 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
|
||||
Class<?> expectedResponseType = this.determineExpectedResponseType(requestMessage);
|
||||
|
||||
HttpEntity<?> httpRequest = this.generateHttpRequest(requestMessage, httpMethod);
|
||||
Map<String, Object> uriVariables = ExpressionEvalMap
|
||||
.from(this.uriVariableExpressions)
|
||||
.usingEvaluationContext(this.evaluationContext)
|
||||
.withRoot(requestMessage)
|
||||
.build();
|
||||
Map<String, ?> uriVariables = this.determineUriVariables(requestMessage);
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromUriString(uri).buildAndExpand(uriVariables);
|
||||
URI realUri = this.encodeUri ? uriComponents.toUri() : new URI(uriComponents.toUriString());
|
||||
ResponseEntity<?> httpResponse = this.restTemplate.exchange(realUri, httpMethod, httpRequest, expectedResponseType);
|
||||
@@ -554,7 +565,6 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
|
||||
return HttpMethod.valueOf(strHttpMethod);
|
||||
}
|
||||
|
||||
|
||||
private Class<?> determineExpectedResponseType(Message<?> requestMessage) throws Exception{
|
||||
Class<?> expectedResponseType = null;
|
||||
String expectedResponseTypeName = null;
|
||||
@@ -568,4 +578,22 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, ?> determineUriVariables(Message<?> requestMessage) {
|
||||
Map<String, ?> expressions;
|
||||
|
||||
if (this.uriVariablesExpression != null) {
|
||||
expressions = this.uriVariablesExpression.getValue(this.evaluationContext, requestMessage, Map.class);
|
||||
}
|
||||
else {
|
||||
expressions = this.uriVariableExpressions;
|
||||
}
|
||||
|
||||
return ExpressionEvalMap.from(expressions)
|
||||
.usingEvaluationContext(this.evaluationContext)
|
||||
.withRoot(requestMessage)
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -322,78 +322,14 @@
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specify an expression for URI variable placeholder within 'url'.
|
||||
This element is mutually exclusive with 'uri-variables-expression' attribute.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="request-handler-advice-chain" type="integration:adviceChainType" minOccurs="0" maxOccurs="1" />
|
||||
</xsd:choice>
|
||||
<xsd:attributeGroup ref="integration:channelAdapterAttributes"/>
|
||||
<xsd:attribute name="url" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
URL to which the requests should be sent. It may include {placeholders} for
|
||||
evaluation against uri-variables.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="url-expression" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
SpEL Expression resolving to a URL to which the requests should be sent. The resolved
|
||||
value may include {placeholders} for further evaluation against uri-variables.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="encode-uri" type="xsd:string" default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
When set to "false", the real URI won't be encoded before the request is sent. This may be useful
|
||||
in some scenarios as it allows user control over the encoding, if needed,
|
||||
for example by using the "url-expression". Default is "true".
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="http-method">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The HTTP method to use when executing requests with this adapter Default is POST.
|
||||
This attribute cannot be provided if http-method-expression has a value.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="httpMethodEnumeration xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="http-method-expression" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The SpEL expression to determine HTTP method, use when executing requests with this adapter,
|
||||
dynamically. This attribute cannot be provided if http-method has a value.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="rest-template" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.web.client.RestTemplate" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
The reference to org.springframework.web.client.RestTemplate bean to send the HTTP Request.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="charset" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specify the charset name to use for converting String-typed payloads to bytes.
|
||||
The default is 'UTF-8'
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attributeGroup ref="httpOutboundCommonAttributes"/>
|
||||
<xsd:attribute name="extract-payload" type="xsd:string" default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
@@ -404,93 +340,6 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expected-response-type" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The expected type to which the response body should be converted.
|
||||
Default is 'org.springframework.http.ResponseEntity'.
|
||||
This attribute cannot be provided if expected-response-type-expression has a value
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="direct">
|
||||
<tool:expected-type type="java.lang.Class" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expected-response-type-expression" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
SpEL expression to determine the type for the expected response to which the response body should be converted
|
||||
The returned value of the expression could be an instance of java.lang.Class or
|
||||
java.lang.String representing a fully qualified class name.
|
||||
This attribute cannot be provided if expected-response-type has a value
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="message-converters" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Provide a reference to a list of HttpMessageConverter instances. If specified, these converters will replace
|
||||
all of the default converters that would normally be present on the underlying RestTemplate.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="header-mapper" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.mapping.HeaderMapper" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Specify a reference to org.springframework.integration.mapping.HeaderMapper
|
||||
implementation bean. Only one of 'header-mapper' or 'mapped-request-headers' attributes
|
||||
can be provided.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mapped-request-headers" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Comma-separated list of names of MessageHeaders to be mapped into the HttpHeaders of the HTTP request.
|
||||
This can only be provided if the 'header-mapper' reference is not being set directly. The values in
|
||||
this list can also be simple patterns to be matched against the header names (e.g. "foo*" or "*foo").
|
||||
The String "HTTP_REQUEST_HEADERS" will match against any of the standard HTTP Request headers.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="request-factory" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Reference to a ClientHttpRequestFactory to be used by the underlying RestTemplate.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.http.client.ClientHttpRequestFactory" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="error-handler" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Reference to a ResponseErrorHandler to be used by the underlying RestTemplate.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.web.client.ResponseErrorHandler" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="order" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specifies the order for invocation when this adapter is connected as a subscriber to a SubscribableChannel.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
@@ -525,96 +374,6 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="url" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
URL to which the requests should be sent. It may include {placeholders} for
|
||||
evaluation against uri-variables.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="url-expression" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
SpEL Expression resolving to a URL to which the requests should be sent. The resolved
|
||||
value may include {placeholders} for further evaluation against uri-variables.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="encode-uri" type="xsd:string" default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
When set to "false", the real URI won't be encoded before the request is sent. This may be useful
|
||||
in some scenarios as it allows user control over the encoding, if needed,
|
||||
for example by using the "url-expression". Default is "true".
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="http-method">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The HTTP method to use when executing requests with this adapter. Default is POST.
|
||||
This attribute cannot be provided if http-method-expression has a value.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="httpMethodEnumeration xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="http-method-expression" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The SpEL expression to determine HTTP method, use when executing requests with this gateway,
|
||||
dynamically. This attribute cannot be provided if http-method has a value.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="message-converters" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Provide a reference to a list of HttpMessageConverter instances. If specified, these converters will replace
|
||||
all of the default converters that would normally be present on the underlying RestTemplate.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="header-mapper" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.mapping.HeaderMapper" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Specifies a reference to org.springframework.integration.mapping.HeaderMapper
|
||||
implementation bean. Only one of 'header-mapper' or 'mapped-request-headers'('mapped-response-headers')
|
||||
attributes
|
||||
can be provided.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="rest-template" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.web.client.RestTemplate" />
|
||||
</tool:annotation>
|
||||
<xsd:documentation>
|
||||
The reference to org.springframework.web.client.RestTemplate bean to send the HTTP Request.
|
||||
</xsd:documentation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mapped-request-headers" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Comma-separated list of names of MessageHeaders to be mapped into the HttpHeaders of the HTTP request.
|
||||
This can only be provided if the 'header-mapper' reference is not being set directly. The values in
|
||||
this list can also be simple patterns to be matched against the header names (e.g. "foo*" or "*foo").
|
||||
The String "HTTP_REQUEST_HEADERS" will match against any of the standard HTTP Request headers.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mapped-response-headers" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
@@ -626,76 +385,13 @@
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="extract-request-payload" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specifies whether the outbound message's payload should be extracted
|
||||
when preparing the request body. Otherwise the Message instance itself
|
||||
will be serialized.
|
||||
The default value is 'true'.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expected-response-type" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The expected type to which the response body should be converted.
|
||||
Default is 'org.springframework.http.ResponseEntity'.
|
||||
This attribute cannot be provided if expected-response-type-expression has a value
|
||||
Specifies whether the outbound message's payload should be extracted
|
||||
when preparing the request body. Otherwise the Message instance itself
|
||||
will be serialized.
|
||||
The default value is 'true'.
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="direct">
|
||||
<tool:expected-type type="java.lang.Class" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expected-response-type-expression" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
SpEL expression to determine the type for the expected response to which the response body should be converted
|
||||
The returned value of the expression could be an instance of java.lang.Class or
|
||||
java.lang.String representing a fully qualified class name.
|
||||
This attribute cannot be provided if expected-response-type has a value
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="charset" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specify the charset name to use for converting String-typed payloads to bytes.
|
||||
The default is 'UTF-8'
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="request-factory" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Reference to a ClientHttpRequestFactory to be used by the underlying RestTemplate.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.http.client.ClientHttpRequestFactory" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="error-handler" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Reference to a ResponseErrorHandler to be used by the underlying RestTemplate.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.web.client.ResponseErrorHandler" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="order" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specifies the order for invocation when this gateway is connected as a subscriber to a SubscribableChannel.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="transfer-cookies" type="xsd:string" default="false">
|
||||
@@ -730,6 +426,7 @@
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attributeGroup ref="httpOutboundCommonAttributes"/>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
@@ -873,4 +570,168 @@
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:attributeGroup name="httpOutboundCommonAttributes">
|
||||
<xsd:attribute name="url" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
URL to which the requests should be sent. It may include {placeholders} for
|
||||
evaluation against uri-variables.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="url-expression" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
SpEL Expression resolving to a URL to which the requests should be sent. The resolved
|
||||
value may include {placeholders} for further evaluation against uri-variables.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="encode-uri" type="xsd:string" default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
When set to "false", the real URI won't be encoded before the request is sent. This may be useful
|
||||
in some scenarios as it allows user control over the encoding, if needed,
|
||||
for example by using the "url-expression". Default is "true".
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="http-method">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The HTTP method to use when executing requests with this adapter Default is POST.
|
||||
This attribute cannot be provided if http-method-expression has a value.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="httpMethodEnumeration xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="http-method-expression" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The SpEL expression to determine HTTP method, use when executing requests with this adapter,
|
||||
dynamically. This attribute cannot be provided if http-method has a value.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="rest-template" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.web.client.RestTemplate" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
The reference to org.springframework.web.client.RestTemplate bean to send the HTTP Request.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="charset" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specify the charset name to use for converting String-typed payloads to bytes.
|
||||
The default is 'UTF-8'
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expected-response-type" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The expected type to which the response body should be converted.
|
||||
Default is 'org.springframework.http.ResponseEntity'.
|
||||
This attribute cannot be provided if expected-response-type-expression has a value
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="direct">
|
||||
<tool:expected-type type="java.lang.Class" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expected-response-type-expression" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
SpEL expression to determine the type for the expected response to which the response body should be converted
|
||||
The returned value of the expression could be an instance of java.lang.Class or
|
||||
java.lang.String representing a fully qualified class name.
|
||||
This attribute cannot be provided if expected-response-type has a value
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="message-converters" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Provide a reference to a list of HttpMessageConverter instances. If specified, these converters will replace
|
||||
all of the default converters that would normally be present on the underlying RestTemplate.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="header-mapper" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.mapping.HeaderMapper" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Specify a reference to org.springframework.integration.mapping.HeaderMapper
|
||||
implementation bean. Only one of 'header-mapper' or 'mapped-request-headers' attributes
|
||||
can be provided.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mapped-request-headers" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Comma-separated list of names of MessageHeaders to be mapped into the HttpHeaders of the HTTP request.
|
||||
This can only be provided if the 'header-mapper' reference is not being set directly. The values in
|
||||
this list can also be simple patterns to be matched against the header names (e.g. "foo*" or "*foo").
|
||||
The String "HTTP_REQUEST_HEADERS" will match against any of the standard HTTP Request headers.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="request-factory" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Reference to a ClientHttpRequestFactory to be used by the underlying RestTemplate.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.http.client.ClientHttpRequestFactory" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="error-handler" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Reference to a ResponseErrorHandler to be used by the underlying RestTemplate.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.web.client.ResponseErrorHandler" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="order" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specifies the order for invocation when this adapter is connected as a subscriber to a SubscribableChannel.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="uri-variables-expression" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specifies the SpEL expression to be evaluate as a Map for URI variable placeholders within 'url'.
|
||||
This attribute is mutually exclusive with 'uri-variable' sub-elements.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:attributeGroup>
|
||||
|
||||
</xsd:schema>
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
<si:channel id="requests"/>
|
||||
|
||||
<outbound-channel-adapter id="minimalConfig" url="http://localhost/test1" channel="requests"/>
|
||||
|
||||
|
||||
<outbound-channel-adapter id="restTemplateConfig" url="http://localhost/test1" channel="requests" rest-template="customRestTemplate"/>
|
||||
|
||||
|
||||
<beans:bean id="customRestTemplate" class="org.springframework.web.client.RestTemplate"/>
|
||||
|
||||
<outbound-channel-adapter id="fullConfig"
|
||||
@@ -34,8 +34,14 @@
|
||||
<uri-variable name="foo" expression="headers.bar"/>
|
||||
</outbound-channel-adapter>
|
||||
|
||||
<util:map id="uriVariables">
|
||||
<beans:entry key="foo1" value="bar1"/>
|
||||
<beans:entry key="foo2" value="bar2"/>
|
||||
</util:map>
|
||||
|
||||
<outbound-channel-adapter id="withUrlAndTemplate"
|
||||
url="http://localhost/test1" channel="requests"
|
||||
uri-variables-expression="@uriVariables"
|
||||
rest-template="customRestTemplate"/>
|
||||
|
||||
<outbound-channel-adapter id="withUrlExpression" url-expression="'http://localhost/test1'" channel="requests"/>
|
||||
|
||||
@@ -57,6 +57,7 @@ import org.springframework.web.client.RestTemplate;
|
||||
* @author Mark Fisher
|
||||
* @author Gary Russell
|
||||
* @author Gunnar Hillert
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
@@ -166,6 +167,7 @@ public class HttpOutboundChannelAdapterParserTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("uchecked")
|
||||
public void withUrlAndTemplate() {
|
||||
DirectFieldAccessor endpointAccessor = new DirectFieldAccessor(this.withUrlAndTemplate);
|
||||
RestTemplate restTemplate =
|
||||
@@ -185,6 +187,14 @@ public class HttpOutboundChannelAdapterParserTests {
|
||||
assertEquals(HttpMethod.POST.name(), TestUtils.getPropertyValue(handler, "httpMethodExpression", Expression.class).getExpressionString());
|
||||
assertEquals("UTF-8", handlerAccessor.getPropertyValue("charset"));
|
||||
assertEquals(true, handlerAccessor.getPropertyValue("extractPayload"));
|
||||
|
||||
//INT-3055
|
||||
Object uriVariablesExpression = handlerAccessor.getPropertyValue("uriVariablesExpression");
|
||||
assertNotNull(uriVariablesExpression);
|
||||
assertEquals("@uriVariables", ((Expression) uriVariablesExpression).getExpressionString());
|
||||
Object uriVariableExpressions = handlerAccessor.getPropertyValue("uriVariableExpressions");
|
||||
assertNotNull(uriVariableExpressions);
|
||||
assertTrue(((Map<?, ?>) uriVariableExpressions).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -40,7 +40,13 @@
|
||||
<uri-variable name="foo" expression="headers.bar"/>
|
||||
</outbound-gateway>
|
||||
|
||||
<outbound-gateway id="withUrlExpression" url-expression="'http://localhost/test1'" request-channel="requests"/>
|
||||
<util:map id="uriVariables">
|
||||
<beans:entry key="foo1" value="bar1"/>
|
||||
<beans:entry key="foo2" value="bar2"/>
|
||||
</util:map>
|
||||
|
||||
<outbound-gateway id="withUrlExpression" url-expression="'http://localhost/test1'" request-channel="requests"
|
||||
uri-variables-expression="@uriVariables"/>
|
||||
|
||||
<outbound-gateway id="withAdvice" url-expression="'http://localhost/test1'" request-channel="requests">
|
||||
<request-handler-advice-chain>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -170,6 +170,14 @@ public class HttpOutboundGatewayParserTests {
|
||||
assertEquals("UTF-8", handlerAccessor.getPropertyValue("charset"));
|
||||
assertEquals(true, handlerAccessor.getPropertyValue("extractPayload"));
|
||||
assertEquals(false, handlerAccessor.getPropertyValue("transferCookies"));
|
||||
|
||||
//INT-3055
|
||||
Object uriVariablesExpression = handlerAccessor.getPropertyValue("uriVariablesExpression");
|
||||
assertNotNull(uriVariablesExpression);
|
||||
assertEquals("@uriVariables", ((Expression) uriVariablesExpression).getExpressionString());
|
||||
Object uriVariableExpressions = handlerAccessor.getPropertyValue("uriVariableExpressions");
|
||||
assertNotNull(uriVariableExpressions);
|
||||
assertTrue(((Map<?, ?>) uriVariableExpressions).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.integration.http.outbound;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -35,7 +36,9 @@ import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.client.ClientHttpRequest;
|
||||
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.expression.ExpressionEvalMap;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -62,14 +65,13 @@ public class UriVariableExpressionTests {
|
||||
handler.setBeanFactory(mock(BeanFactory.class));
|
||||
handler.afterPropertiesSet();
|
||||
Message<?> message = new GenericMessage<Object>("bar");
|
||||
Exception exception = null;
|
||||
try {
|
||||
handler.handleMessage(message);
|
||||
fail("Exception expected.");
|
||||
}
|
||||
catch (Exception e) {
|
||||
exception = e;
|
||||
assertEquals("intentional", e.getCause().getMessage());
|
||||
}
|
||||
assertEquals("intentional", exception.getCause().getMessage());
|
||||
assertEquals("http://test/bar", uriHolder.get().toString());
|
||||
}
|
||||
|
||||
@@ -92,15 +94,45 @@ public class UriVariableExpressionTests {
|
||||
});
|
||||
handler.setBeanFactory(mock(BeanFactory.class));
|
||||
handler.afterPropertiesSet();
|
||||
Message<?> message = new GenericMessage<Object>("bar");
|
||||
Exception exception = null;
|
||||
try {
|
||||
handler.handleMessage(message);
|
||||
handler.handleMessage(new GenericMessage<Object>("bar"));
|
||||
fail("Exception expected.");
|
||||
}
|
||||
catch (Exception e) {
|
||||
exception = e;
|
||||
assertEquals("intentional", e.getCause().getMessage());
|
||||
}
|
||||
assertEquals("intentional", exception.getCause().getMessage());
|
||||
assertEquals("http://test/bar", uriHolder.get().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInt3055UriVariablesExpression() throws Exception {
|
||||
final AtomicReference<URI> uriHolder = new AtomicReference<URI>();
|
||||
HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler("http://test/{foo}");
|
||||
|
||||
handler.setRequestFactory(new SimpleClientHttpRequestFactory() {
|
||||
@Override
|
||||
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
|
||||
uriHolder.set(uri);
|
||||
throw new RuntimeException("intentional");
|
||||
}
|
||||
});
|
||||
handler.setBeanFactory(mock(BeanFactory.class));
|
||||
handler.setUriVariablesExpression(new SpelExpressionParser().parseExpression("headers.uriVariables"));
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
Map<String, String> expressions = new HashMap<String, String>();
|
||||
expressions.put("foo", "bar");
|
||||
|
||||
Map<String, ?> expressionsMap = ExpressionEvalMap.from(expressions).usingSimpleCallback().build();
|
||||
|
||||
try {
|
||||
handler.handleMessage(MessageBuilder.withPayload("test").setHeader("uriVariables", expressionsMap).build());
|
||||
fail("Exception expected.");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertEquals("intentional", e.getCause().getMessage());
|
||||
}
|
||||
|
||||
assertEquals("http://test/bar", uriHolder.get().toString());
|
||||
}
|
||||
|
||||
|
||||
@@ -520,6 +520,43 @@ By default the HTTP request will be generated using an instance of <classname>Si
|
||||
method will be invoked on the payload object of the Message and the result
|
||||
of that method will be used as the value for the URI variable named 'zipCode'.
|
||||
</para>
|
||||
<para>
|
||||
Since <emphasis>Spring Integration 3.0</emphasis>, HTTP Outbound Endpoints support the
|
||||
<code>uri-variables-expression</code> attribute to specify an <interfacename>Expression</interfacename>
|
||||
which should be evaluated, resulting in a
|
||||
<interfacename>Map</interfacename> for all URI variable placeholders within the URL template. It provides
|
||||
a mechanism whereby different variable expressions can be used, based on the outbound message.
|
||||
This attribute is mutually exclusive with the <code><uri-variable/></code> sub-element:
|
||||
<programlisting language="xml"><![CDATA[<int-http:outbound-gateway
|
||||
url="http://foo.host/{foo}/bars/{bar}"
|
||||
request-channel="trafficChannel"
|
||||
http-method="GET"
|
||||
uri-variables-expression="@uriVariablesBean.populate(payload)"
|
||||
expected-response-type="java.lang.String"/>]]></programlisting>
|
||||
where <code>uriVariablesBean</code> might be:
|
||||
<programlisting language="java"><![CDATA[public class UriVariablesBean {
|
||||
private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();
|
||||
|
||||
public Map<String, ?> populate(Object payload) {
|
||||
Map<String, Object> variables = new HashMap<String, Object>();
|
||||
if (payload instanceOf String.class)) {
|
||||
variables.put("foo", "foo"));
|
||||
}
|
||||
else {
|
||||
variables.put("foo", EXPRESSION_PARSER.parseExpression("headers.bar"));
|
||||
}
|
||||
return variables;
|
||||
}
|
||||
|
||||
}]]></programlisting>
|
||||
</para>
|
||||
<note>
|
||||
The <code>uri-variables-expression</code> must evaluate to a <interfacename>Map</interfacename>.
|
||||
The values of the Map must be instances of
|
||||
<interfacename>String</interfacename> or <interfacename>Expression</interfacename>.
|
||||
This Map is provided to an <classname>ExpressionEvalMap</classname> for further resolution of URI variable placeholders
|
||||
using those expressions in the context of the outbound <interfacename>Message</interfacename>.
|
||||
</note>
|
||||
<para>
|
||||
<emphasis>Controlling URI Encoding</emphasis>
|
||||
</para>
|
||||
|
||||
@@ -431,6 +431,13 @@
|
||||
<emphasis>#requestHeaders</emphasis> and <emphasis>#cookies</emphasis>. These variables are available in
|
||||
both payload and header expressions.
|
||||
</listitem>
|
||||
<listitem>
|
||||
<emphasis role="bold">Outbound Endpoint 'uri-variables-expression'</emphasis> - HTTP Outbound Endpoints
|
||||
now support the <code>uri-variables-expression</code> attribute to specify
|
||||
an <interfacename>Expression</interfacename> to evaluate a <interfacename>Map</interfacename>
|
||||
for all URI variable placeholders within URL template. This allows selection of a different
|
||||
map of expressions based on the outgoing message.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
|
||||
Reference in New Issue
Block a user