INT-1677 added support for expressions

This commit is contained in:
Oleg Zhurakousky
2011-09-01 14:02:38 -04:00
committed by Mark Fisher
parent 897bc887a1
commit 224db99c15
2 changed files with 124 additions and 144 deletions

View File

@@ -21,6 +21,7 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -38,6 +39,7 @@ import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.expression.spel.support.StandardTypeConverter;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
@@ -97,8 +99,6 @@ import org.springframework.web.util.UriTemplate;
*/
abstract class HttpRequestHandlingEndpointSupport extends MessagingGatewaySupport {
private static final ExpressionParser PARSER = new SpelExpressionParser();
private static final boolean jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder",
HttpRequestHandlingEndpointSupport.class.getClassLoader());
@@ -130,7 +130,7 @@ abstract class HttpRequestHandlingEndpointSupport extends MessagingGatewaySuppor
private volatile Expression payloadExpression;
private volatile List<Expression> headerExpressions;
private volatile Map<String, Expression> headerExpressions;
public HttpRequestHandlingEndpointSupport() {
this(true);
@@ -176,7 +176,7 @@ abstract class HttpRequestHandlingEndpointSupport extends MessagingGatewaySuppor
this.payloadExpression = payloadExpression;
}
public void setHeaderExpressions(List<Expression> headerExpressions) {
public void setHeaderExpressions(Map<String, Expression> headerExpressions) {
this.headerExpressions = headerExpressions;
}
/**
@@ -303,27 +303,51 @@ abstract class HttpRequestHandlingEndpointSupport extends MessagingGatewaySuppor
if (StringUtils.hasText(this.path)){
UriTemplate template = new UriTemplate(this.path);
uriVariableMappings = template.match(request.getURI().getPath());
if (logger.isDebugEnabled()){
logger.debug("Mapped URI variables: " + uriVariableMappings);
if (!uriVariableMappings.isEmpty()){
if (logger.isDebugEnabled()){
logger.debug("Mapped URI variables: " + uriVariableMappings);
}
// set the whole map
this.evaluationContext.setVariable("uriVariables", uriVariableMappings);
for (Object key : uriVariableMappings.keySet()) {
// add individual elements
this.evaluationContext.setVariable((String) key, uriVariableMappings.get(key));
}
}
else {
logger.warn("Was not able to match UriVariables to path: " + this.path);
}
}
//
Map<String, ?> headers = this.headerMapper.toHeaders(request.getHeaders());
Object payload = null;
if (this.isReadable(request)) {
payload = this.extractRequestBody(request);
headers.putAll(uriVariableMappings);
}
else {
payload = this.convertParameterMap(servletRequest.getParameterMap());
if (payload instanceof Map){
for (Object key : uriVariableMappings.keySet()) {
((Map) payload).put(key, Collections.singletonList(uriVariableMappings.get(key)));
}
Object payload = null;
if (this.payloadExpression != null){
// create payload based on SpEL
payload = this.payloadExpression.getValue(this.evaluationContext, request);
}
if (this.headerExpressions != null){
for (String headerName : this.headerExpressions.keySet()) {
Expression headerExpression = this.headerExpressions.get(headerName);
Object headerValue = headerExpression.getValue(this.evaluationContext, request);
((Map<String, Object>)headers).put(headerName, headerValue);
}
}
if (payload == null){
if (this.isReadable(request)) {
payload = this.extractRequestBody(request);
}
else {
payload = this.convertParameterMap(servletRequest.getParameterMap());
}
}
HttpEntity entity = new HttpEntity(request.getBody(), request.getHeaders());
Message<?> message = MessageBuilder.withPayload(payload).copyHeaders(headers).setHeader(
org.springframework.integration.http.HttpHeaders.REQUEST_URL, request.getURI().toString())
@@ -372,7 +396,7 @@ abstract class HttpRequestHandlingEndpointSupport extends MessagingGatewaySuppor
if (this.multipartResolver != null && this.multipartResolver.isMultipart(servletRequest)) {
return new MultipartHttpInputMessage(this.multipartResolver.resolveMultipart(servletRequest));
}
return new SmartServletServerHttpRequest(servletRequest);
return new ServletServerHttpRequest(servletRequest);
}
/**
@@ -443,39 +467,4 @@ abstract class HttpRequestHandlingEndpointSupport extends MessagingGatewaySuppor
}
return httpStatus;
}
public class SmartServletServerHttpRequest extends ServletServerHttpRequest{
private final Map<String, Object> requestParamMap;
@SuppressWarnings("rawtypes")
private final Map uriVarsMap;
@SuppressWarnings({ "rawtypes", "unchecked" })
public SmartServletServerHttpRequest(HttpServletRequest servletRequest) {
//servletRequest.getp
super(servletRequest);
requestParamMap = servletRequest.getParameterMap();
Map uriVariableMappings = null;
//
if (StringUtils.hasText(HttpRequestHandlingEndpointSupport.this.path)){
UriTemplate template = new UriTemplate(HttpRequestHandlingEndpointSupport.this.path);
uriVariableMappings = template.match(this.getURI().getPath());
if (logger.isDebugEnabled()){
logger.debug("Mapped URI variables: " + uriVariableMappings);
}
}
uriVarsMap = uriVariableMappings;
}
public Map<String, Object> getRequestParamMap() {
return requestParamMap;
}
@SuppressWarnings("rawtypes")
public Map getUriVars() {
return uriVarsMap;
}
}
}

View File

@@ -16,87 +16,39 @@
package org.springframework.integration.http.inbound;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.expression.spel.support.StandardTypeConverter;
import org.springframework.http.HttpHeaders;
import org.springframework.integration.Message;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.MessagingException;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageHandler;
import org.springframework.integration.http.MockHttpServletRequest;
import org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport.SmartServletServerHttpRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.util.CollectionUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* @author Oleg Zhurakousky
*/
public class HttpRequestHandlingMessagingGatewayWithPathMappingTests {
@Test
public void defaultUriVariableMappingWithPOST() throws Exception {
QueueChannel requestChannel = new QueueChannel();
HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway(false);
gateway.setPath("/fname/{f}/lname/{l}");
gateway.setRequestChannel(requestChannel);
MockHttpServletRequest request = new MockHttpServletRequest();
request.setMethod("POST");
request.setContentType("text/plain");
request.setParameter("foo", "bar");
request.setContent("hello".getBytes());
request.setRequestURI("/fname/bill/lname/clinton");
MockHttpServletResponse response = new MockHttpServletResponse();
gateway.handleRequest(request, response);
Message<?> message = requestChannel.receive(0);
assertNotNull(message);
assertEquals("bill", message.getHeaders().get("f"));
assertEquals("clinton", message.getHeaders().get("l"));
}
private static ExpressionParser PARSER = new SpelExpressionParser();
@SuppressWarnings("rawtypes")
@Test
public void defaultUriVariableMappingWithGET() throws Exception {
QueueChannel requestChannel = new QueueChannel();
HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway(false);
gateway.setPath("/fname/{f}/lname/{l}");
gateway.setRequestChannel(requestChannel);
MockHttpServletRequest request = new MockHttpServletRequest();
request.setMethod("GET");
request.setParameter("foo", "bar");
request.setRequestURI("/fname/bill/lname/clinton");
MockHttpServletResponse response = new MockHttpServletResponse();
gateway.handleRequest(request, response);
Message<?> message = requestChannel.receive(0);
assertNotNull(message);
assertNull(message.getHeaders().get("f"));
assertNull(message.getHeaders().get("l"));
Map payload = (Map) message.getPayload();
assertEquals(Collections.singletonList("bill"), payload.get("f"));
assertEquals(Collections.singletonList("clinton"), payload.get("l"));
}
/**
* This is a temporary test which simply shows what would happen inside of the gateway which has an internal
* capability for SpEL based extraction of data such as UriVariabe mappings, HttpHeaders, Body and Request Parameters.
*
* @throws Exception
*/
@Test
public void withExpression() throws Exception {
public void withoutExpression() throws Exception {
DirectChannel echoChannel = new DirectChannel();
echoChannel.subscribe(new MessageHandler() {
public void handleMessage(Message<?> message) throws MessagingException {
MessageChannel replyChannel = (MessageChannel) message.getHeaders().getReplyChannel();
replyChannel.send(message);
}
});
MockHttpServletRequest request = new MockHttpServletRequest();
request.setMethod("POST");
request.setContentType("text/plain");
@@ -106,39 +58,78 @@ public class HttpRequestHandlingMessagingGatewayWithPathMappingTests {
HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway(true);
gateway.setPath("/fname/{f}/lname/{l}");
gateway.setRequestChannel(echoChannel);
SmartServletServerHttpRequest smartRequest = gateway.new SmartServletServerHttpRequest(request);
MockHttpServletResponse response = new MockHttpServletResponse();
StandardEvaluationContext context = new StandardEvaluationContext();
ConversionService conversionService = ConversionServiceFactory.createDefaultConversionService();
Object result = gateway.doHandleRequest(request, response);
assertEquals("hello", result);
context.setTypeConverter(new StandardTypeConverter(conversionService));
ExpressionParser parser = new SpelExpressionParser();
Expression bodyExpression = parser.parseExpression("body");
InputStream body = bodyExpression.getValue(context, smartRequest, InputStream.class);
assertNotNull(body);
assertEquals("hello", this.convertToString(body));
Expression headersExpression = parser.parseExpression("headers['Content-Type']");
List<?> headers = headersExpression.getValue(context, smartRequest, List.class);
assertNotNull(headers);
assertEquals("text/plain", headers.get(0));
Expression uriVarsExpression = parser.parseExpression("uriVars['f']");
String fname = uriVarsExpression.getValue(context, smartRequest, String.class);
assertNotNull(fname);
assertEquals("bill", fname);
}
public String convertToString(InputStream in) throws IOException {
StringBuffer out = new StringBuffer();
byte[] b = new byte[4096];
for (int n; (n = in.read(b)) != -1;) {
out.append(new String(b, 0, n));
}
return out.toString();
@Test
public void withoutPayloadExpressionPointingToUriVariable() throws Exception {
DirectChannel echoChannel = new DirectChannel();
echoChannel.subscribe(new MessageHandler() {
public void handleMessage(Message<?> message) throws MessagingException {
MessageChannel replyChannel = (MessageChannel) message.getHeaders().getReplyChannel();
replyChannel.send(message);
}
});
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
request.setMethod("POST");
request.setContentType("text/plain");
request.setParameter("foo", "bar");
request.setContent("hello".getBytes());
request.setRequestURI("/fname/bill/lname/clinton");
HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway(true);
gateway.setPath("/fname/{f}/lname/{l}");
gateway.setRequestChannel(echoChannel);
gateway.setPayloadExpression(PARSER.parseExpression("#f"));
Object result = gateway.doHandleRequest(request, response);
assertEquals("bill", result);
}
@Test
public void withoutPayloadExpressionPointingToUriVariables() throws Exception {
DirectChannel echoChannel = new DirectChannel();
echoChannel.subscribe(new MessageHandler() {
public void handleMessage(Message<?> message) throws MessagingException {
MessageChannel replyChannel = (MessageChannel) message.getHeaders().getReplyChannel();
replyChannel.send(message);
}
});
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
request.setMethod("POST");
request.setContentType("text/plain");
request.setParameter("foo", "bar");
request.setContent("hello".getBytes());
request.setRequestURI("/fname/bill/lname/clinton");
HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway(true);
gateway.setPath("/fname/{f}/lname/{l}");
gateway.setRequestChannel(echoChannel);
gateway.setPayloadExpression(PARSER.parseExpression("#uriVariables"));
Object result = gateway.doHandleRequest(request, response);
assertEquals("bill", ((Map)result).get("f"));
}
}