INT-3052 RestTemplate with TypeReference for HTTP

JIRA: https://jira.springsource.org/browse/INT-3052

Add support of `ParameterizedTypeReference` as a result of
`expectedResponseTypeExpression` evaluation for
`RestTemplate.exchange` with `ParameterizedTypeReference` parameter

Now `expectedResponseTypeExpression` can be evaluated to `Class<?>`,
`String` and `ParameterizedTypeReference<?>`
This commit is contained in:
Artem Bilan
2013-12-17 17:17:13 +02:00
parent 73a104c955
commit 64cc1faafe
5 changed files with 71 additions and 20 deletions

View File

@@ -36,6 +36,11 @@
message-converters="stringAndSerializingConverters"
expected-response-type-expression="payload"/>
<int-http:outbound-gateway url="http://localhost:#{portBean.port}/testApps/outboundResponse"
request-channel="invalidResponseTypeChannel"
expected-response-type-expression="new java.util.Date()"/>
<util:list id="stringAndSerializingConverters">
<bean class="org.springframework.integration.http.converter.SerializingHttpMessageConverter" />
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />

View File

@@ -16,6 +16,7 @@
package org.springframework.integration.http.config;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -23,21 +24,24 @@ import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import org.hamcrest.Matchers;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.integration.MessageHandlingException;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.test.util.SocketUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.integration.test.util.SocketUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -80,6 +84,9 @@ public class OutboundResponseTypeTests {
@Autowired
private MessageChannel resTypeExpressionSetSerializationChannel;
@Autowired
private MessageChannel invalidResponseTypeChannel;
private static int port = SocketUtils.findAvailableServerSocket();
@BeforeClass
@@ -143,6 +150,21 @@ public class OutboundResponseTypeTests {
assertTrue(message.getPayload() instanceof byte[]);
}
@Test
public void testInt3052InvalidResponseType() throws Exception {
try {
this.invalidResponseTypeChannel.send(new GenericMessage<byte[]>("hello".getBytes()));
fail("IllegalArgumentException expected.");
}
catch (Exception e) {
assertThat(e, Matchers.instanceOf(MessageHandlingException.class));
Throwable t = e.getCause();
assertThat(t, Matchers.instanceOf(IllegalArgumentException.class));
assertThat(t.getMessage(),
Matchers.containsString("'expectedResponseType' can be an instance of 'Class<?>', 'String' or 'ParameterizedTypeReference<?>'"));
}
}
@Test
public void testMutuallyExclusivityInMethodAndMethodExpression() throws Exception {
try {

View File

@@ -22,7 +22,7 @@
<outbound-gateway url="http://localhost:51235/%2f/testApps?param={param}"
rest-template="restTemplate"
encode-uri="false"
expected-response-type="java.lang.String">
expected-response-type-expression="T (org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandlerTests).testParameterizedTypeReference()">
<uri-variable name="param" expression="T(org.apache.commons.httpclient.util.URIUtil).encodeWithinQuery('http Outbound Gateway Within Chain')"/>
</outbound-gateway>
</si:chain>

View File

@@ -52,6 +52,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.ConverterRegistry;
import org.springframework.expression.spel.standard.SpelExpressionParser;
@@ -65,14 +66,14 @@ import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.messaging.PollableChannel;
import org.springframework.integration.http.converter.SerializingHttpMessageConverter;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.PollableChannel;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
@@ -86,6 +87,10 @@ import org.springframework.web.client.RestTemplate;
*/
public class HttpRequestExecutingMessageHandlerTests {
public static ParameterizedTypeReference<List<String>> testParameterizedTypeReference() {
return new ParameterizedTypeReference<List<String>>() {};
}
@Test
public void simpleStringKeyStringValueFormData() throws Exception {
HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler("http://www.springsource.org/spring-integration");
@@ -726,10 +731,12 @@ public class HttpRequestExecutingMessageHandlerTests {
PollableChannel output = ctx.getBean("replyChannel", PollableChannel.class);
Message<?> receive = output.receive();
assertEquals(HttpStatus.OK, ((ResponseEntity<?>)receive.getPayload()).getStatusCode());
assertEquals(HttpStatus.OK, ((ResponseEntity<?>) receive.getPayload()).getStatusCode());
Mockito.verify(restTemplate)
.exchange(Mockito.eq(new URI("http://localhost:51235/%2f/testApps?param=http%20Outbound%20Gateway%20Within%20Chain")),
Mockito.eq(HttpMethod.POST), Mockito.any(HttpEntity.class), Mockito.eq(String.class));
Mockito.eq(HttpMethod.POST), Mockito.any(HttpEntity.class), Mockito.eq(new ParameterizedTypeReference<List<String>>() {
}));
}
@Test
@@ -938,6 +945,12 @@ public class HttpRequestExecutingMessageHandlerTests {
Class<T> responseType) throws RestClientException {
return new ResponseEntity<T>(HttpStatus.OK);
}
@Override
public <T> ResponseEntity<T> exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity,
ParameterizedTypeReference<T> responseType) throws RestClientException {
return new ResponseEntity<T>(HttpStatus.OK);
}
}
private static class Foo implements Serializable {