You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2017/06/02 00:00:31 UTC
[2/3] incubator-juneau git commit: Improvements to
@Query/@FormData/@Header/@Path remoteable annotations.
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>()