http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-core/src/main/javadoc/overview.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/javadoc/overview.html 
b/juneau-core/src/main/javadoc/overview.html
index a4e6885..ef06af5 100644
--- a/juneau-core/src/main/javadoc/overview.html
+++ b/juneau-core/src/main/javadoc/overview.html
@@ -6231,7 +6231,9 @@
        <ja>@BeanProperty</ja>(<js>"foo"</js>)
                                </p>
                        <li>Fixed a race condition in ClassMeta.
-                       
+                       <li><jsf>URLENC_paramFormat</jsf> has been moved to 
{@link org.apache.juneau.uon.UonSerializerContext#UON_paramFormat}, 
+                               and the UON/URL-Encoding serializers will now 
always serialize all values as plain text.
+                               <br>This means that arrays and maps are 
converted to simple comma-delimited lists.
                </ul>
 
                <h6 class='topic'>org.apache.juneau.rest</h6>
@@ -6463,11 +6465,11 @@
                                <br><ja>@Remoteable</ja> annotation has been 
moved to this package.
                        <li>Updated doc: <a class='doclink' 
href='#Remoteable'>6 - Remoteable Services</a>
                        <li>New doc: <a class='doclink' 
href='#Remoteable.3rdParty'>6.1 -  Interface proxies against 3rd-party REST 
interfaces</a>
-                       <li>New URL-encoding serializer setting: {@link 
org.apache.juneau.urlencoding.UrlEncodingSerializerContext#URLENC_paramFormat}
+                       <li>New URL-encoding serializer setting: 
<code><del>UrlEncodingSerializerContext.URLENC_paramFormat</del></code>.
                        <li>New methods on {@link 
org.apache.juneau.urlencoding.UrlEncodingSerializerBuilder}:
                        <ul>
                                <li>{@link 
org.apache.juneau.urlencoding.UrlEncodingSerializerBuilder#paramFormat(String) 
paramFormat(String)}  
-                               <li>{@link 
org.apache.juneau.urlencoding.UrlEncodingSerializerBuilder#plainTextParams() 
plainTextParams()}      
+                               
<li><code><del>UrlEncodingSerializerBuilder.plainTextParams()</del></code>      
                        </ul>           
                </ul>
                
@@ -6626,7 +6628,7 @@
                                <ul>
                                        <li>{@link 
org.apache.juneau.rest.client.RestClientBuilder#executorService(ExecutorService,boolean)
 executorService(ExecutorService,boolean)}
                                        <li>{@link 
org.apache.juneau.rest.client.RestClientBuilder#paramFormat(String) 
paramFormat(ExecutorService,boolean)}
-                                       <li>{@link 
org.apache.juneau.rest.client.RestClientBuilder#plainTextParams() 
plainTextParams()}
+                                       
<li><code><del>RestClientBuilder.plainTextParams()</del></code>
                                        <li>{@link 
org.apache.juneau.rest.client.RestClientBuilder#noTrace() noTrace()} - Adds a 
<code>No-Trace: true</code> header on all requests to prevent
                                                the servlet from logging errors.
                                                <br>Useful for testing 
scenarios when you don't want the console to end up showing errors done on 
purpose.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java 
b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
index 769e5eb..9be6df6 100644
--- 
a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
+++ 
b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
@@ -28,6 +28,7 @@ import org.apache.http.client.config.*;
 import org.apache.http.client.entity.*;
 import org.apache.http.client.methods.*;
 import org.apache.http.client.utils.*;
+import org.apache.http.entity.*;
 import org.apache.http.impl.client.*;
 import org.apache.http.util.*;
 import org.apache.juneau.*;
@@ -37,6 +38,7 @@ import org.apache.juneau.internal.ObjectUtils;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.parser.ParseException;
 import org.apache.juneau.serializer.*;
+import org.apache.juneau.urlencoding.*;
 import org.apache.juneau.utils.*;
 
 /**
@@ -191,16 +193,22 @@ public final class RestCall {
                                uriBuilder.addParameter(name, 
partSerializer.serialize(PartType.QUERY, value));
                } else if (value instanceof NameValuePairs) {
                        for (NameValuePair p : (NameValuePairs)value)
-                               query(p.getName(), p.getValue(), skipIfEmpty, 
partSerializer);
-               } else if (value instanceof String) {
-                       String s = value.toString();
-                       if (! isEmpty(s))
-                               uriBuilder.setCustomQuery(s);
+                               query(p.getName(), p.getValue(), skipIfEmpty, 
UrlEncodingSerializer.DEFAULT_PLAINTEXT);
                } else if (value instanceof Map) {
                        for (Map.Entry<String,Object> p : ((Map<String,Object>) 
value).entrySet())
                                query(p.getKey(), p.getValue(), skipIfEmpty, 
partSerializer);
-               } else if (isBean(value)){
+               } else if (isBean(value)) {
                        return query(name, toBeanMap(value), skipIfEmpty, 
partSerializer);
+               } else if (value instanceof Reader) {
+                       try {
+                               uriBuilder.setCustomQuery(IOUtils.read(value));
+                       } catch (IOException e) {
+                               throw new RestCallException(e);
+                       }
+               } else if (value instanceof CharSequence) {
+                       String s = value.toString();
+                       if (! isEmpty(s))
+                               uriBuilder.setCustomQuery(s);
                } else {
                        throw new FormattedRuntimeException("Invalid name 
''{0}'' passed to query(name,value,skipIfEmpty) for data type ''{1}''", name, 
ClassUtils.getReadableClassNameForObject(value));
                }
@@ -291,13 +299,21 @@ public final class RestCall {
                                formData.add(new SerializedNameValuePair(name, 
value, partSerializer));
                } else if (value instanceof NameValuePairs) {
                        for (NameValuePair p : (NameValuePairs)value)
-                               if (! (isEmpty(p.getValue()) && skipIfEmpty))
+                               if (p.getValue() != null && ! 
(isEmpty(p.getValue()) && skipIfEmpty))
                                        formData.add(p);
                } else if (value instanceof Map) {
                        for (Map.Entry<String,Object> p : ((Map<String,Object>) 
value).entrySet())
                                formData(p.getKey(), p.getValue(), skipIfEmpty, 
partSerializer);
                } else if (isBean(value)) {
                        return formData(name, toBeanMap(value), skipIfEmpty, 
partSerializer);
+               } else if (value instanceof Reader) {
+                       contentType("application/x-www-form-urlencoded");
+                       input(value);
+               } else if (value instanceof CharSequence) {
+                       try {
+                               
contentType("application/x-www-form-urlencoded");
+                               input(new StringEntity(value.toString()));
+                       } catch (UnsupportedEncodingException e) {}
                } else {
                        throw new FormattedRuntimeException("Invalid name 
''{0}'' passed to formData(name,value,skipIfEmpty) for data type ''{1}''", 
name, ClassUtils.getReadableClassNameForObject(value));
                }
@@ -389,13 +405,13 @@ public final class RestCall {
                        uriBuilder.setPath(newPath);
                } else if (value instanceof NameValuePairs) {
                        for (NameValuePair p : (NameValuePairs)value)
-                               path(p.getName(), p.getValue());
+                               path(p.getName(), p.getValue(), partSerializer);
                } else if (value instanceof Map) {
                        for (Map.Entry<String,Object> p : ((Map<String,Object>) 
value).entrySet())
-                               path(p.getKey(), p.getValue());
+                               path(p.getKey(), p.getValue(), partSerializer);
                } else if (isBean(value)) {
-                       return path(name, toBeanMap(value));
-               } else {
+                       return path(name, toBeanMap(value), partSerializer);
+               } else if (value != null) {
                        throw new FormattedRuntimeException("Invalid name 
''{0}'' passed to path(name,value) for data type ''{1}''", name, 
ClassUtils.getReadableClassNameForObject(value));
                }
                return this;
@@ -454,6 +470,7 @@ public final class RestCall {
        public RestCall input(final Object input) throws RestCallException {
                this.input = input;
                this.hasInput = true;
+               this.formData = null;
                return this;
        }
 
@@ -508,7 +525,7 @@ public final class RestCall {
                                request.setHeader(name, 
partSerializer.serialize(PartType.HEADER, value));
                } else if (value instanceof NameValuePairs) {
                        for (NameValuePair p : (NameValuePairs)value)
-                               header(p.getName(), p.getValue(), skipIfEmpty, 
partSerializer);
+                               header(p.getName(), p.getValue(), skipIfEmpty, 
UrlEncodingSerializer.DEFAULT_PLAINTEXT);
                } else if (value instanceof Map) {
                        for (Map.Entry<String,Object> p : ((Map<String,Object>) 
value).entrySet())
                                header(p.getKey(), p.getValue(), skipIfEmpty, 
partSerializer);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
 
b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
index 8f26768..910a9fb 100644
--- 
a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
+++ 
b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
@@ -567,39 +567,42 @@ public class RestClient extends CoreObject {
                                                        if 
(rmm.getRequestBeanArgs().length > 0) {
                                                                BeanSession bs 
= getBeanContext().createSession();
 
-                                                               for (Integer i 
: rmm.getRequestBeanArgs()) {
-                                                                       
BeanMap<?> bm = bs.toBeanMap(args[i]);
-                                                                       for 
(BeanPropertyValue bpv : bm.getValues(true)) {
+                                                               for 
(RemoteMethodArg rma : rmm.getRequestBeanArgs()) {
+                                                                       
BeanMap<?> bm = bs.toBeanMap(args[rma.index]);
+
+                                                                       for 
(BeanPropertyValue bpv : bm.getValues(false)) {
                                                                                
BeanPropertyMeta pMeta = bpv.getMeta();
                                                                                
Object val = bpv.getValue();
 
                                                                                
Path p = pMeta.getAnnotation(Path.class);
                                                                                
if (p != null)
-                                                                               
        rc.path(getName(p.value(), pMeta), val, 
getPartSerializer(p.serializer()));
+                                                                               
        rc.path(getName(p.name(), p.value(), pMeta), val, 
getPartSerializer(p.serializer(), rma.serializer));
 
-                                                                               
Query q1 = pMeta.getAnnotation(Query.class);
-                                                                               
if (q1 != null)
-                                                                               
        rc.query(getName(q1.value(), pMeta), val, false, 
getPartSerializer(q1.serializer()));
+                                                                               
if (val != null) {
+                                                                               
        Query q1 = pMeta.getAnnotation(Query.class);
+                                                                               
        if (q1 != null)
+                                                                               
                rc.query(getName(q1.name(), q1.value(), pMeta), val, 
q1.skipIfEmpty(), getPartSerializer(q1.serializer(), rma.serializer));
 
-                                                                               
QueryIfNE q2 = pMeta.getAnnotation(QueryIfNE.class);
-                                                                               
if (q2 != null)
-                                                                               
        rc.query(getName(q2.value(), pMeta), val, true, 
getPartSerializer(q2.serializer()));
+                                                                               
        QueryIfNE q2 = pMeta.getAnnotation(QueryIfNE.class);
+                                                                               
        if (q2 != null)
+                                                                               
                rc.query(getName(q2.name(), q2.value(), pMeta), val, true, 
getPartSerializer(q2.serializer(), rma.serializer));
 
-                                                                               
FormData f1 = pMeta.getAnnotation(FormData.class);
-                                                                               
if (f1 != null)
-                                                                               
        rc.formData(getName(f1.value(), pMeta), val, false, 
getPartSerializer(f1.serializer()));
+                                                                               
        FormData f1 = pMeta.getAnnotation(FormData.class);
+                                                                               
        if (f1 != null)
+                                                                               
                rc.formData(getName(f1.name(), f1.value(), pMeta), val, 
f1.skipIfEmpty(), getPartSerializer(f1.serializer(), rma.serializer));
 
-                                                                               
FormDataIfNE f2 = pMeta.getAnnotation(FormDataIfNE.class);
-                                                                               
if (f2 != null)
-                                                                               
        rc.formData(getName(f2.value(), pMeta), val, true, 
getPartSerializer(f2.serializer()));
+                                                                               
        FormDataIfNE f2 = pMeta.getAnnotation(FormDataIfNE.class);
+                                                                               
        if (f2 != null)
+                                                                               
                rc.formData(getName(f2.name(), f2.value(), pMeta), val, true, 
getPartSerializer(f2.serializer(), rma.serializer));
 
-                                                                               
org.apache.juneau.remoteable.Header h1 = 
pMeta.getAnnotation(org.apache.juneau.remoteable.Header.class);
-                                                                               
if (h1 != null)
-                                                                               
        rc.header(getName(h1.value(), pMeta), val, false, 
getPartSerializer(h1.serializer()));
+                                                                               
        org.apache.juneau.remoteable.Header h1 = 
pMeta.getAnnotation(org.apache.juneau.remoteable.Header.class);
+                                                                               
        if (h1 != null)
+                                                                               
                rc.header(getName(h1.name(), h1.value(), pMeta), val, 
h1.skipIfEmpty(), getPartSerializer(h1.serializer(), rma.serializer));
 
-                                                                               
HeaderIfNE h2 = pMeta.getAnnotation(HeaderIfNE.class);
-                                                                               
if (h2 != null)
-                                                                               
        rc.header(getName(h2.value(), pMeta), val, true, 
getPartSerializer(h2.serializer()));
+                                                                               
        HeaderIfNE h2 = pMeta.getAnnotation(HeaderIfNE.class);
+                                                                               
        if (h2 != null)
+                                                                               
                rc.header(getName(h2.name(), h2.value(), pMeta), val, true, 
getPartSerializer(h2.serializer(), rma.serializer));
+                                                                               
}
                                                                        }
                                                                }
                                                        }
@@ -628,14 +631,20 @@ public class RestClient extends CoreObject {
                }
        }
 
-       private static String getName(String name, BeanPropertyMeta pMeta) {
-               if ("*".equals(name) && ! pMeta.getClassMeta().isMapOrBean())
-                       name = pMeta.getName();
-               return name;
+       private static String getName(String name1, String name2, 
BeanPropertyMeta pMeta) {
+               String n = name1.isEmpty() ? name2 : name1;
+               ClassMeta<?> cm = pMeta.getClassMeta();
+               if (n.isEmpty() && (cm.isMapOrBean() || cm.isReader() || 
cm.isInstanceOf(NameValuePairs.class)))
+                       n = "*";
+               if (n.isEmpty())
+                       n = pMeta.getName();
+               return n;
        }
 
-       private static PartSerializer getPartSerializer(Class c) {
-               if (c == UrlEncodingSerializer.class)
+       private static PartSerializer getPartSerializer(Class c, PartSerializer 
c2) {
+               if (c2 != null)
+                       return c2;
+               if (c == PartSerializer.class)
                        return null;
                PartSerializer pf = partSerializerCache.get(c);
                if (pf == null) {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
 
b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
index 463920a..65b4dc8 100644
--- 
a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
+++ 
b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
@@ -46,6 +46,7 @@ import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.serializer.*;
+import org.apache.juneau.uon.*;
 import org.apache.juneau.urlencoding.*;
 
 /**
@@ -1101,7 +1102,7 @@ public class RestClientBuilder extends CoreObjectBuilder {
        }
 
        /**
-        * Sets the {@link UrlEncodingSerializerContext#URLENC_paramFormat} 
property on the URL-encoding serializers in this group.
+        * Sets the {@link UonSerializerContext#UON_paramFormat} property on 
the URL-encoding serializers in this group.
         * <p>
         * This overrides the behavior of the URL-encoding serializer to quote 
and escape characters
         * in query names and values that may be confused for UON notation 
(e.g. <js>"'(foo=123)'"</js>, <js>"'@(1,2,3)'"</js>).
@@ -1109,20 +1110,34 @@ public class RestClientBuilder extends 
CoreObjectBuilder {
         *
         * @param value The new value for this property.
         * @return This object (for method chaining).
-        * @see UrlEncodingSerializerContext#URLENC_paramFormat
+        * @see UonSerializerContext#UON_paramFormat
         */
        public RestClientBuilder paramFormat(String value) {
-               super.property(UrlEncodingSerializerContext.URLENC_paramFormat, 
value);
+               super.property(UonSerializerContext.UON_paramFormat, value);
                return this;
        }
 
        /**
         * Shortcut for calling <code>paramFormat(<js>"PLAINTEXT"</js>)</code>.
+        * <p>
+        * The default behavior is to serialize part values (query parameters, 
form data, headers, path variables) in UON notation.
+        * Calling this method forces plain-text to be used instead.
+        * <p>
+        * Specifially, UON notation has the following effects:
+        * <ul>
+        *      <li>Boolean strings (<js>"true"</js>/<js>"false"</js>) and 
numeric values (<js>"123"</js>) will be
+        *                      quoted (<js>"'true'"</js>, <js>"'false'"</js>, 
<js>"'123'"</js>.
+        *              <br>This allows them to be differentiated from actual 
boolean and numeric values.
+        *      <li>String such as <js>"(foo='bar')"</js> that mimic UON 
structures will be quoted and escaped to
+        *              <js>"'(foo=bar~'baz~')'"</js>.
+        * </ul>
+        * <p>
+        * The downside to using plain text part serialization is that you 
cannot serialize arbitrary POJOs.
         *
         * @return This object (for method chaining).
         */
-       public RestClientBuilder plainTextParams() {
-               super.property(UrlEncodingSerializerContext.URLENC_paramFormat, 
"PLAINTEXT");
+       public RestClientBuilder plainTextParts() {
+               super.property(UonSerializerContext.UON_paramFormat, 
"PLAINTEXT");
                return this;
        }
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/RequestBeanProxyResource.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/RequestBeanProxyResource.java
 
b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/RequestBeanProxyResource.java
new file mode 100644
index 0000000..eed0679
--- /dev/null
+++ 
b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/RequestBeanProxyResource.java
@@ -0,0 +1,50 @@
+// 
***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not 
use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                
                                              *
+// *                                                                           
                                              *
+// *  http://www.apache.org/licenses/LICENSE-2.0                               
                                              *
+// *                                                                           
                                              *
+// * Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the 
License.                                              *
+// 
***************************************************************************************************************************
+package org.apache.juneau.rest.test;
+
+
+import java.io.*;
+
+import org.apache.juneau.microservice.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+
+/**
+ * Validates the functionality of <ja>@RequestBeans</ja>.
+ */
+@RestResource(
+       path="/testRequestBeanProxy"
+)
+@SuppressWarnings("serial")
+public class RequestBeanProxyResource extends ResourceJena {
+
+       @RestMethod(name="GET", path="/echoQuery")
+       public Reader echoQuery(RestRequest req) throws Exception {
+               return new StringReader(req.getQuery().toString(true));
+       }
+
+       @RestMethod(name="POST", path="/echoFormData")
+       public Reader echoFormData(RestRequest req) throws Exception {
+               return new StringReader(req.getFormData().toString(true));
+       }
+
+       @RestMethod(name="GET", path="/echoHeaders")
+       public Reader echoHeaders(RestRequest req) throws Exception {
+               return new 
StringReader(req.getHeaders().subset("a,b,c,d,e,f,g,h,i,a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4").toString(true));
+       }
+
+       @RestMethod(name="GET", path="/echoPath/*")
+       public Reader echoPath(RestRequest req) throws Exception {
+               return new StringReader(req.getPathMatch().getRemainder());
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java 
b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
index f04181b..3bee867 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
@@ -60,6 +60,7 @@ import org.apache.juneau.rest.labels.*;
                PathVariablesResource.class,
                PropertiesResource.class,
                QueryResource.class,
+               RequestBeanProxyResource.class,
                RestClient2Resource.class,
                SerializersResource.class,
                StaticFilesResource.class,

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/93aadae1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/FormDataTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/FormDataTest.java 
b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/FormDataTest.java
index 9aeff98..d0f1874 100644
--- 
a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/FormDataTest.java
+++ 
b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/FormDataTest.java
@@ -68,7 +68,7 @@ public class FormDataTest extends RestTestcase {
        
//====================================================================================================
        @Test
        public void testPlainTextParams() throws Exception {
-               RestClient c = 
TestMicroservice.client(UrlEncodingSerializer.class, 
UrlEncodingParser.class).plainTextParams().build();
+               RestClient c = 
TestMicroservice.client(UrlEncodingSerializer.class, 
UrlEncodingParser.class).plainTextParts().build();
                String r;
 
                Map<String,Object> m = new AMap<String,Object>()

Reply via email to