Author: wtam Date: Wed Apr 21 01:51:03 2010 New Revision: 936136 URL: http://svn.apache.org/viewvc?rev=936136&view=rev Log: Applied patch from Rich Bolen to address [CAMEL-2638] Restlet component is URL encoding the POST message body. It should encode it based on content-type request header
Modified: camel/trunk/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/DefaultRestletBinding.java camel/trunk/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestletRouteBuilderTest.java Modified: camel/trunk/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/DefaultRestletBinding.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/DefaultRestletBinding.java?rev=936136&r1=936135&r2=936136&view=diff ============================================================================== --- camel/trunk/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/DefaultRestletBinding.java (original) +++ camel/trunk/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/DefaultRestletBinding.java Wed Apr 21 01:51:03 2010 @@ -35,6 +35,7 @@ import org.restlet.data.ChallengeScheme; import org.restlet.data.CharacterSet; import org.restlet.data.Form; import org.restlet.data.MediaType; +import org.restlet.data.Method; import org.restlet.data.Request; import org.restlet.data.Response; import org.restlet.data.Status; @@ -105,8 +106,13 @@ public class DefaultRestletBinding imple // add the body as the key in the form with null value form.add(body, null); + MediaType mediaType = exchange.getIn().getHeader(Exchange.CONTENT_TYPE, MediaType.class); + if (mediaType == null) { + mediaType = MediaType.APPLICATION_WWW_FORM; + } + if (LOG.isDebugEnabled()) { - LOG.debug("Populate Restlet request from exchange body: " + body); + LOG.debug("Populate Restlet request from exchange body: " + body + " using media type " + mediaType); } // login and password are filtered by header filter strategy @@ -123,12 +129,19 @@ public class DefaultRestletBinding imple for (Map.Entry<String, Object> entry : exchange.getIn().getHeaders().entrySet()) { if (!headerFilterStrategy.applyFilterToCamelHeaders(entry.getKey(), entry.getValue(), exchange)) { - if (entry.getKey().startsWith("org.restlet.")) { - // put the org.restlet headers in attributes + // Use forms only for GET and POST/x-www-form-urlencoded + if (request.getMethod() == Method.GET || (request.getMethod() == Method.POST && mediaType == MediaType.APPLICATION_WWW_FORM)) { + if (entry.getKey().startsWith("org.restlet.")) { + // put the org.restlet headers in attributes + request.getAttributes().put(entry.getKey(), entry.getValue()); + } else { + // put the user stuff in the form + form.add(entry.getKey(), entry.getValue().toString()); + } + } + else { + // For non-form post put all the headers in attributes request.getAttributes().put(entry.getKey(), entry.getValue()); - } else { - // put the user stuff in the form - form.add(entry.getKey(), entry.getValue().toString()); } if (LOG.isDebugEnabled()) { LOG.debug("Populate Restlet request from exchange header: " @@ -137,7 +150,18 @@ public class DefaultRestletBinding imple } } - request.setEntity(form.getWebRepresentation()); + if (LOG.isDebugEnabled()) { + LOG.debug("Using Content Type: " + + mediaType + " for POST data: " + body); + } + + // Only URL Encode for GET and form POST + if (request.getMethod() == Method.GET || (request.getMethod() == Method.POST && mediaType == MediaType.APPLICATION_WWW_FORM)) { + request.setEntity(form.getWebRepresentation()); + } + else { + request.setEntity(body, mediaType); + } } public void populateRestletResponseFromExchange(Exchange exchange, Response response) { Modified: camel/trunk/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestletRouteBuilderTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestletRouteBuilderTest.java?rev=936136&r1=936135&r2=936136&view=diff ============================================================================== --- camel/trunk/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestletRouteBuilderTest.java (original) +++ camel/trunk/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestletRouteBuilderTest.java Wed Apr 21 01:51:03 2010 @@ -25,6 +25,7 @@ import org.apache.camel.builder.RouteBui import org.apache.camel.test.junit4.CamelTestSupport; import org.junit.Test; import org.restlet.Client; +import org.restlet.data.MediaType; import org.restlet.data.Method; import org.restlet.data.Protocol; import org.restlet.data.Request; @@ -33,6 +34,7 @@ import org.restlet.data.Status; public class RestletRouteBuilderTest extends CamelTestSupport { private static final String ID = "89531"; + private static final String JSON = "{\"document type\": \"JSON\"}"; @Override protected RouteBuilder createRouteBuilder() { @@ -54,6 +56,17 @@ public class RestletRouteBuilderTest ext } }); + // Restlet consumer to handler POST method + from("restlet:http://localhost:9080/ordersJSON?restletMethod=post").process(new Processor() { + public void process(Exchange exchange) throws Exception { + String body = exchange.getIn().getBody(String.class); + if (body.indexOf("{") == -1) { + throw new Exception("Inproperly formatted JSON: " + body ); + } + exchange.getOut().setBody(exchange.getIn().getBody()); + } + }); + // Restlet consumer default to handle GET method from("restlet:http://localhost:9080/orders/{id}/{x}").process(new Processor() { public void process(Exchange exchange) throws Exception { @@ -81,6 +94,30 @@ public class RestletRouteBuilderTest ext } @Test + public void testProducerJSON() throws IOException { + String response = (String)template.sendBodyAndHeader( + "restlet:http://localhost:9080/ordersJSON?restletMethod=post&foo=bar", + ExchangePattern.InOut, + JSON, + Exchange.CONTENT_TYPE, + MediaType.APPLICATION_JSON); + + assertEquals(JSON, response); + } + + + @Test + public void testProducerJSONFailure() throws IOException { + + String response = (String)template.sendBody( + "restlet:http://localhost:9080/ordersJSON?restletMethod=post&foo=bar", + ExchangePattern.InOut, + "{'JSON'}"); + + assertEquals("{'JSON'}", response); + } + + @Test public void testConsumer() throws IOException { Client client = new Client(Protocol.HTTP); Response response = client.handle(new Request(Method.GET,