INT-1760, INT-1759 Http outbound gateway response type
Change the default expected response type to ResponseEntity Add support for expected-response-type-expression attribute to accept SpEL to determine expected response type. INT-1760, INT-1759 add documentation. INT-1760, INT-1759 polished javadocs and schema doc INT-1760, INT-1759 more polishing INT-1760, INT-1759 polished documentation based on PR INT-1760 Polishing Fix Chain test.
This commit is contained in:
committed by
Gary Russell
parent
e6520821d1
commit
6bbe8057ab
@@ -114,4 +114,30 @@ abstract class HttpAdapterParsingUtils {
|
||||
}
|
||||
}
|
||||
|
||||
static void setExpectedResponseOrExpression(Element element, ParserContext parserContext, BeanDefinitionBuilder builder){
|
||||
String expectedResponseType = element.getAttribute("expected-response-type");
|
||||
String expectedResponseTypeExpression = element.getAttribute("expected-response-type-expression");
|
||||
|
||||
boolean hasExpectedResponseType = StringUtils.hasText(expectedResponseType);
|
||||
boolean hasExpectedResponseTypeExpression = StringUtils.hasText(expectedResponseTypeExpression);
|
||||
|
||||
if (hasExpectedResponseType && hasExpectedResponseTypeExpression){
|
||||
parserContext.getReaderContext().error("The 'expected-response-type' and 'expected-response-type-expression' are mutually exclusive. " +
|
||||
"You can only have one or the other", element);
|
||||
}
|
||||
|
||||
RootBeanDefinition expressionDef = null;
|
||||
if (hasExpectedResponseType) {
|
||||
expressionDef = new RootBeanDefinition(LiteralExpression.class);
|
||||
expressionDef.getConstructorArgumentValues().addGenericArgumentValue(expectedResponseType);
|
||||
}
|
||||
else if (hasExpectedResponseTypeExpression){
|
||||
expressionDef = new RootBeanDefinition(ExpressionFactoryBean.class);
|
||||
expressionDef.getConstructorArgumentValues().addGenericArgumentValue(expectedResponseTypeExpression);
|
||||
}
|
||||
if (expressionDef != null){
|
||||
builder.addPropertyValue("expectedResponseTypeExpression", expressionDef);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class HttpOutboundChannelAdapterParser extends AbstractOutboundChannelAda
|
||||
}
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "charset");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "extract-payload");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "expected-response-type");
|
||||
HttpAdapterParsingUtils.setExpectedResponseOrExpression(element, parserContext, builder);
|
||||
HttpAdapterParsingUtils.configureUriVariableExpressions(builder, element);
|
||||
return builder.getBeanDefinition();
|
||||
}
|
||||
|
||||
@@ -79,7 +79,9 @@ public class HttpOutboundGatewayParser extends AbstractConsumerEndpointParser {
|
||||
}
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "charset");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "extract-request-payload", "extractPayload");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "expected-response-type");
|
||||
|
||||
HttpAdapterParsingUtils.setExpectedResponseOrExpression(element, parserContext, builder);
|
||||
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "reply-timeout", "sendTimeout");
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "reply-channel", "outputChannel");
|
||||
HttpAdapterParsingUtils.configureUriVariableExpressions(builder, element);
|
||||
|
||||
@@ -31,6 +31,8 @@ import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.context.expression.BeanFactoryResolver;
|
||||
import org.springframework.context.expression.MapAccessor;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.common.LiteralExpression;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
@@ -89,7 +91,7 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
|
||||
|
||||
private volatile boolean expectReply = true;
|
||||
|
||||
private volatile Class<?> expectedResponseType;
|
||||
private volatile Expression expectedResponseTypeExpression;
|
||||
|
||||
private volatile boolean extractPayload = true;
|
||||
|
||||
@@ -198,13 +200,26 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the expected response type for the REST request.
|
||||
* If this is null (the default), only the status code will be returned
|
||||
* as the reply Message payload. To take advantage of the HttpMessageConverters
|
||||
* Specify the expected response type for the REST request
|
||||
* otherwise the default response type is {@link ResponseEntity} and will
|
||||
* be returned as a payload of the reply Message.
|
||||
* To take advantage of the HttpMessageConverters
|
||||
* registered on this adapter, provide a different type).
|
||||
* Also see {@link #setExpectedResponseTypeExpression(Expression)}
|
||||
*/
|
||||
public void setExpectedResponseType(Class<?> expectedResponseType) {
|
||||
this.expectedResponseType = expectedResponseType;
|
||||
Assert.notNull(expectedResponseType, "'expectedResponseType' must not be null");
|
||||
this.expectedResponseTypeExpression = new LiteralExpression(expectedResponseType.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the {@link Expression} to determine the type for the expected response
|
||||
* The returned value of the expression could be an instance of {@link Class} or
|
||||
* {@link String} representing a fully qualified class name
|
||||
* Also see {@link #setExpectedResponseTypeExpression(Expression)}
|
||||
*/
|
||||
public void setExpectedResponseTypeExpression(Expression expectedResponseTypeExpression) {
|
||||
this.expectedResponseTypeExpression = expectedResponseTypeExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -269,8 +284,19 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
|
||||
this.evaluationContext.setBeanResolver(new BeanFactoryResolver(beanFactory));
|
||||
}
|
||||
ConversionService conversionService = this.getConversionService();
|
||||
if (conversionService == null){
|
||||
conversionService = new GenericConversionService();
|
||||
}
|
||||
Assert.isInstanceOf(GenericConversionService.class, conversionService);
|
||||
GenericConversionService gConversionService = (GenericConversionService) conversionService;
|
||||
gConversionService.addConverter(new Converter<Class<?>, String>() {
|
||||
public String convert(Class<?> source) {
|
||||
return source.getName();
|
||||
}
|
||||
});
|
||||
|
||||
if (conversionService != null) {
|
||||
this.evaluationContext.setTypeConverter(new StandardTypeConverter(conversionService));
|
||||
this.evaluationContext.setTypeConverter(new StandardTypeConverter(gConversionService));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,8 +320,10 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
|
||||
}
|
||||
}
|
||||
|
||||
Class<?> expectedResponseType = this.determineExpectedResponseType(requestMessage);
|
||||
|
||||
HttpEntity<?> httpRequest = this.generateHttpRequest(requestMessage, httpMethod);
|
||||
ResponseEntity<?> httpResponse = this.restTemplate.exchange(uri, httpMethod, httpRequest, this.expectedResponseType, uriVariables);
|
||||
ResponseEntity<?> httpResponse = this.restTemplate.exchange(uri, httpMethod, httpRequest, expectedResponseType, uriVariables);
|
||||
if (this.expectReply) {
|
||||
HttpHeaders httpHeaders = httpResponse.getHeaders();
|
||||
Map<String, Object> headers = this.headerMapper.toHeaders(httpHeaders);
|
||||
@@ -310,7 +338,7 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
|
||||
return replyBuilder.copyHeaders(headers).build();
|
||||
}
|
||||
else {
|
||||
return MessageBuilder.withPayload(httpResponse.getStatusCode()).
|
||||
return MessageBuilder.withPayload(httpResponse).
|
||||
copyHeaders(headers).setHeader(org.springframework.integration.http.HttpHeaders.STATUS_CODE, httpResponse.getStatusCode()).
|
||||
build();
|
||||
}
|
||||
@@ -490,4 +518,16 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
|
||||
"The 'httpMethodExpression' returned an invalid HTTP Method value: " + strHttpMethod);
|
||||
return HttpMethod.valueOf(strHttpMethod);
|
||||
}
|
||||
|
||||
private Class<?> determineExpectedResponseType(Message<?> requestMessage) throws Exception{
|
||||
Class<?> expectedResponseType = null;
|
||||
String expectedResponseTypeName = null;
|
||||
if (this.expectedResponseTypeExpression != null){
|
||||
expectedResponseTypeName = this.expectedResponseTypeExpression.getValue(this.evaluationContext, requestMessage, String.class);
|
||||
}
|
||||
if (StringUtils.hasText(expectedResponseTypeName)){
|
||||
expectedResponseType = Class.forName(expectedResponseTypeName);
|
||||
}
|
||||
return expectedResponseType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -411,7 +411,9 @@ The String "HTTP_REQUEST_HEADERS" will match against any of the standard HTTP Re
|
||||
<xsd:attribute name="expected-response-type" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The expected type to which the response body should be converted.
|
||||
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">
|
||||
@@ -420,6 +422,16 @@ The String "HTTP_REQUEST_HEADERS" will match against any of the standard HTTP Re
|
||||
</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>
|
||||
@@ -595,7 +607,9 @@ The String "HTTP_REQUEST_HEADERS" will match against any of the standard HTTP Re
|
||||
<xsd:attribute name="expected-response-type" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The expected type to which the response body should be converted.
|
||||
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">
|
||||
@@ -604,6 +618,16 @@ The String "HTTP_REQUEST_HEADERS" will match against any of the standard HTTP Re
|
||||
</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:attribute name="request-factory" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
|
||||
Reference in New Issue
Block a user