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 2020/07/06 21:44:01 UTC
[juneau] branch master updated: Docs and tests.
This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new fa12ed5 Docs and tests.
fa12ed5 is described below
commit fa12ed568d5cf68e8f4087320352868fdd901eaf
Author: JamesBognar <ja...@salesforce.com>
AuthorDate: Mon Jul 6 17:43:49 2020 -0400
Docs and tests.
---
.../test/java/org/apache/juneau/MaxIndentTest.java | 4 +-
.../rttests/RoundTripPrimitiveObjectBeansTest.java | 4 +-
.../apache/juneau/config/ConfigInterfaceTest.java | 32 +-
.../org/apache/juneau}/testutils/Constants.java | 2 +-
.../apache/juneau}/testutils/XPartSerializer.java | 2 +-
.../org/apache/juneau/testutils/pojos/ABean.java | 9 +-
.../apache/juneau/testutils/pojos/LargePojo.java | 2 +-
.../pojos/PrimitiveAtomicObjectsBean.java | 6 +-
.../testutils/pojos/PrimitiveObjectsBean.java | 6 +-
.../juneau/testutils/pojos/TypedBeanImpl.java | 6 +-
.../org/apache/juneau/testutils/pojos/XBeans.java | 263 ++++++
.../org/apache/juneau/http/HeaderSupplier.java | 66 +-
.../apache/juneau/http/NameValuePairSupplier.java | 66 +-
.../org/apache/juneau/http/header/BasicHeader.java | 4 +-
.../java/org/apache/juneau/http/remote/Remote.java | 27 +-
.../juneau/jsonschema/annotation/Schema.java | 7 +-
.../java/org/apache/juneau/svl/VarResolver.java | 11 +
juneau-doc/docs/Topics/09.juneau-rest-client.html | 47 +-
.../09.juneau-rest-client/01.PojoMarshalling.html | 8 +-
.../09.juneau-rest-client/02.RequestHeaders.html | 42 +-
.../03.RequestQueryParameters.html | 41 +-
.../09.juneau-rest-client/04.RequestFormData.html | 49 ++
.../09.juneau-rest-client/05.RequestBody.html | 27 +
.../09.juneau-rest-client/08.ResponseBody.html | 10 +-
.../09.CustomCallHandlers.html | 29 +
.../09.juneau-rest-client/10.Interceptors.html | 49 +-
.../09.juneau-rest-client/11.RestProxies.html | 87 +-
.../11.RestProxies/01.Remote.html | 136 +++-
.../11.RestProxies/02.RemoteMethod.html | 2 +-
.../11.RestProxies/03.Body.html | 23 +-
.../11.RestProxies/04.FormData.html | 18 +-
.../11.RestProxies/05.Query.html | 18 +-
.../11.RestProxies/06.Header.html | 14 +-
.../11.RestProxies/07.Path.html | 12 +-
.../11.RestProxies/08.Request.html | 17 +-
.../11.RestProxies/09.Response.html | 13 +-
.../11.RestProxies/10.DualPurposeInterfaces.html | 19 +-
.../12.LoggingAndDebugging.html | 9 +-
.../13.CustomizingHttpClient.html | 2 +-
.../15.Authentication/01.BASIC.html | 14 +-
.../15.Authentication/02.FORM.html | 63 +-
.../15.Authentication/03.OIDC.html | 110 +--
juneau-doc/src/main/javadoc/overview.html | 882 ++++++++++++++-------
.../src/main/javadoc/resources/fragments/toc.html | 4 +-
.../juneau/rest/test/LargePojosResource.java | 2 +-
.../rest/test/client/ThirdPartyProxyResource.java | 5 +-
.../rest/test/client/ThirdPartyProxyTest.java | 4 +-
.../client2/Remote_FormDataAnnotation_Test.java | 2 +-
.../rest/client2/Remote_HeaderAnnotation_Test.java | 2 +-
.../rest/client2/Remote_PathAnnotation_Test.java | 2 +-
.../rest/client2/Remote_QueryAnnotation_Test.java | 2 +-
.../client2/Remote_RequestAnnotation_Test.java | 2 +-
.../juneau/rest/client2/RrpcInterfaceTest.java | 4 +-
.../juneau/rest/client/remote/RemoteMeta.java | 25 +-
.../org/apache/juneau/rest/client2/RestClient.java | 2 +-
.../juneau/rest/client2/RestClientBuilder.java | 2 +-
.../org/apache/juneau/rest/testutils/ABean.java | 32 -
.../org/apache/juneau/rest/testutils/DTOs.java | 142 ----
.../org/apache/juneau/rest/testutils/DTOs2.java | 143 ----
.../juneau/rest/testutils/ImplicitSwappedPojo.java | 35 -
.../apache/juneau/rest/testutils/SwappedPojo.java | 20 -
.../juneau/rest/testutils/SwappedPojoSwap.java | 35 -
.../org/apache/juneau/rest/testutils/TestEnum.java | 17 -
.../apache/juneau/rest/testutils/TypedBean.java | 17 -
.../juneau/rest/testutils/TypedBeanImpl.java | 26 -
.../rest/annotation2/BodyAnnotationTest.java | 38 +-
.../rest/annotation2/FormDataAnnotationTest.java | 2 +-
.../rest/annotation2/HeaderAnnotationTest.java | 2 +-
.../rest/annotation2/PathAnnotationTest.java | 2 +-
.../annotation2/PathRemainderAnnotationTest.java | 2 +-
.../rest/annotation2/QueryAnnotationTest.java | 2 +-
.../apache/juneau/rest/testutils/TestUtils.java | 0
72 files changed, 1676 insertions(+), 1155 deletions(-)
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/MaxIndentTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/MaxIndentTest.java
index 94d25fb..c8e70b6 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/MaxIndentTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/MaxIndentTest.java
@@ -236,7 +236,7 @@ public class MaxIndentTest {
public static class List1dOfBeans extends LinkedList<ABean> {
public List1dOfBeans init1() {
- add(new ABean().init());
+ add(ABean.get());
return this;
}
}
@@ -250,7 +250,7 @@ public class MaxIndentTest {
public static class Map1dOfBeans extends LinkedHashMap<String,ABean> {
public Map1dOfBeans init1() {
- put("a", new ABean().init());
+ put("a", ABean.get());
return this;
}
}
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitiveObjectBeansTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitiveObjectBeansTest.java
index 2052b21..01d7364 100755
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitiveObjectBeansTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitiveObjectBeansTest.java
@@ -37,7 +37,7 @@ public class RoundTripPrimitiveObjectBeansTest extends RoundTripTest {
//====================================================================================================
@Test
public void testPrimitiveObjectsBean() throws Exception {
- PrimitiveObjectsBean t = new PrimitiveObjectsBean().init();
+ PrimitiveObjectsBean t = PrimitiveObjectsBean.get();
t = roundTrip(t, PrimitiveObjectsBean.class);
t = roundTrip(t, PrimitiveObjectsBean.class);
@@ -161,7 +161,7 @@ public class RoundTripPrimitiveObjectBeansTest extends RoundTripTest {
if (getSerializer() instanceof RdfSerializer)
return;
- PrimitiveAtomicObjectsBean t = new PrimitiveAtomicObjectsBean().init();
+ PrimitiveAtomicObjectsBean t = PrimitiveAtomicObjectsBean.get();
t = roundTrip(t, PrimitiveAtomicObjectsBean.class);
t = roundTrip(t, PrimitiveAtomicObjectsBean.class);
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/config/ConfigInterfaceTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/config/ConfigInterfaceTest.java
index 12a1b4c..2b8a1a0 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/config/ConfigInterfaceTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/config/ConfigInterfaceTest.java
@@ -157,7 +157,7 @@ public class ConfigInterfaceTest {
@Test
public void testBean() throws Exception {
- proxy.setBean(new ABean().init());
+ proxy.setBean(ABean.get());
assertObject(proxy.getBean()).json().is("{a:1,b:'foo'}");
assertEquals("{a:1,b:'foo'}", cf.get("A/bean"));
assertObject(proxy.getBean()).isType(ABean.class);
@@ -165,7 +165,7 @@ public class ConfigInterfaceTest {
@Test
public void testBean3dArray() throws Exception {
- proxy.setBean3dArray(new ABean[][][]{{{new ABean().init(),null},null},null});
+ proxy.setBean3dArray(new ABean[][][]{{{ABean.get(),null},null},null});
assertObject(proxy.getBean3dArray()).json().is("[[[{a:1,b:'foo'},null],null],null]");
assertEquals("[[[{a:1,b:'foo'},null],null],null]", cf.get("A/bean3dArray"));
assertObject(proxy.getBean3dArray()[0][0][0]).isType(ABean.class);
@@ -173,7 +173,7 @@ public class ConfigInterfaceTest {
@Test
public void testBeanList() throws Exception {
- proxy.setBeanList(Arrays.asList(new ABean().init()));
+ proxy.setBeanList(Arrays.asList(ABean.get()));
assertObject(proxy.getBeanList()).json().is("[{a:1,b:'foo'}]");
assertEquals("[{a:1,b:'foo'}]", cf.get("A/beanList"));
assertObject(proxy.getBeanList().get(0)).isType(ABean.class);
@@ -181,7 +181,7 @@ public class ConfigInterfaceTest {
@Test
public void testBean1d3dList() throws Exception {
- proxy.setBean1d3dList(AList.of(new ABean[][][]{{{new ABean().init(),null},null},null},null));
+ proxy.setBean1d3dList(AList.of(new ABean[][][]{{{ABean.get(),null},null},null},null));
assertObject(proxy.getBean1d3dList()).json().is("[[[[{a:1,b:'foo'},null],null],null],null]");
assertEquals("[[[[{a:1,b:'foo'},null],null],null],null]", cf.get("A/bean1d3dList"));
assertObject(proxy.getBean1d3dList().get(0)[0][0][0]).isType(ABean.class);
@@ -189,7 +189,7 @@ public class ConfigInterfaceTest {
@Test
public void testBeanMap() throws Exception {
- proxy.setBeanMap(AMap.of("foo",new ABean().init()));
+ proxy.setBeanMap(AMap.of("foo",ABean.get()));
assertObject(proxy.getBeanMap()).json().is("{foo:{a:1,b:'foo'}}");
assertEquals("{foo:{a:1,b:'foo'}}", cf.get("A/beanMap"));
assertObject(proxy.getBeanMap().get("foo")).isType(ABean.class);
@@ -197,7 +197,7 @@ public class ConfigInterfaceTest {
@Test
public void testBeanListMap() throws Exception {
- proxy.setBeanListMap(AMap.of("foo",Arrays.asList(new ABean().init())));
+ proxy.setBeanListMap(AMap.of("foo",Arrays.asList(ABean.get())));
assertObject(proxy.getBeanListMap()).json().is("{foo:[{a:1,b:'foo'}]}");
assertEquals("{foo:[{a:1,b:'foo'}]}", cf.get("A/beanListMap"));
assertObject(proxy.getBeanListMap().get("foo").get(0)).isType(ABean.class);
@@ -205,7 +205,7 @@ public class ConfigInterfaceTest {
@Test
public void testBean1d3dListMap() throws Exception {
- proxy.setBean1d3dListMap(AMap.of("foo",AList.of(new ABean[][][]{{{new ABean().init(),null},null},null},null)));
+ proxy.setBean1d3dListMap(AMap.of("foo",AList.of(new ABean[][][]{{{ABean.get(),null},null},null},null)));
assertObject(proxy.getBean1d3dListMap()).json().is("{foo:[[[[{a:1,b:'foo'},null],null],null],null]}");
assertEquals("{foo:[[[[{a:1,b:'foo'},null],null],null],null]}", cf.get("A/bean1d3dListMap"));
assertObject(proxy.getBean1d3dListMap().get("foo").get(0)[0][0][0]).isType(ABean.class);
@@ -213,7 +213,7 @@ public class ConfigInterfaceTest {
@Test
public void testBeanListMapIntegerKeys() throws Exception {
- proxy.setBeanListMapIntegerKeys(AMap.of(1,Arrays.asList(new ABean().init())));
+ proxy.setBeanListMapIntegerKeys(AMap.of(1,Arrays.asList(ABean.get())));
assertObject(proxy.getBeanListMapIntegerKeys()).json().is("{'1':[{a:1,b:'foo'}]}");
assertEquals("{'1':[{a:1,b:'foo'}]}", cf.get("A/beanListMapIntegerKeys"));
assertObject(proxy.getBeanListMapIntegerKeys().get(1).get(0)).isType(ABean.class);
@@ -223,7 +223,7 @@ public class ConfigInterfaceTest {
@Test
public void testTypedBean() throws Exception {
- proxy.setTypedBean(new TypedBeanImpl().init());
+ proxy.setTypedBean(TypedBeanImpl.get());
assertObject(proxy.getTypedBean()).json().is("{_type:'TypedBeanImpl',a:1,b:'foo'}");
assertEquals("{_type:'TypedBeanImpl',a:1,b:'foo'}", cf.get("A/typedBean"));
assertObject(proxy.getTypedBean()).isType(TypedBeanImpl.class);
@@ -231,7 +231,7 @@ public class ConfigInterfaceTest {
@Test
public void testTypedBean3dArray() throws Exception {
- proxy.setTypedBean3dArray(new TypedBean[][][]{{{new TypedBeanImpl().init(),null},null},null});
+ proxy.setTypedBean3dArray(new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null});
assertObject(proxy.getTypedBean3dArray()).json().is("[[[{_type:'TypedBeanImpl',a:1,b:'foo'},null],null],null]");
assertEquals("[[[{_type:'TypedBeanImpl',a:1,b:'foo'},null],null],null]", cf.get("A/typedBean3dArray"));
assertObject(proxy.getTypedBean3dArray()[0][0][0]).isType(TypedBeanImpl.class);
@@ -239,7 +239,7 @@ public class ConfigInterfaceTest {
@Test
public void testTypedBeanList() throws Exception {
- proxy.setTypedBeanList(Arrays.asList((TypedBean)new TypedBeanImpl().init()));
+ proxy.setTypedBeanList(Arrays.asList((TypedBean)TypedBeanImpl.get()));
assertObject(proxy.getTypedBeanList()).json().is("[{_type:'TypedBeanImpl',a:1,b:'foo'}]");
assertEquals("[{_type:'TypedBeanImpl',a:1,b:'foo'}]", cf.get("A/typedBeanList"));
assertObject(proxy.getTypedBeanList().get(0)).isType(TypedBeanImpl.class);
@@ -247,7 +247,7 @@ public class ConfigInterfaceTest {
@Test
public void testTypedBean1d3dList() throws Exception {
- proxy.setTypedBean1d3dList(AList.of(new TypedBean[][][]{{{new TypedBeanImpl().init(),null},null},null},null));
+ proxy.setTypedBean1d3dList(AList.of(new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null},null));
assertObject(proxy.getTypedBean1d3dList()).json().is("[[[[{_type:'TypedBeanImpl',a:1,b:'foo'},null],null],null],null]");
assertEquals("[[[[{_type:'TypedBeanImpl',a:1,b:'foo'},null],null],null],null]", cf.get("A/typedBean1d3dList"));
assertObject(proxy.getTypedBean1d3dList().get(0)[0][0][0]).isType(TypedBeanImpl.class);
@@ -255,7 +255,7 @@ public class ConfigInterfaceTest {
@Test
public void testTypedBeanMap() throws Exception {
- proxy.setTypedBeanMap(AMap.of("foo",new TypedBeanImpl().init()));
+ proxy.setTypedBeanMap(AMap.of("foo",TypedBeanImpl.get()));
assertObject(proxy.getTypedBeanMap()).json().is("{foo:{_type:'TypedBeanImpl',a:1,b:'foo'}}");
assertEquals("{foo:{_type:'TypedBeanImpl',a:1,b:'foo'}}", cf.get("A/typedBeanMap"));
assertObject(proxy.getTypedBeanMap().get("foo")).isType(TypedBeanImpl.class);
@@ -263,7 +263,7 @@ public class ConfigInterfaceTest {
@Test
public void testTypedBeanListMap() throws Exception {
- proxy.setTypedBeanListMap(AMap.of("foo",Arrays.asList((TypedBean)new TypedBeanImpl().init())));
+ proxy.setTypedBeanListMap(AMap.of("foo",Arrays.asList((TypedBean)TypedBeanImpl.get())));
assertObject(proxy.getTypedBeanListMap()).json().is("{foo:[{_type:'TypedBeanImpl',a:1,b:'foo'}]}");
assertEquals("{foo:[{_type:'TypedBeanImpl',a:1,b:'foo'}]}", cf.get("A/typedBeanListMap"));
assertObject(proxy.getTypedBeanListMap().get("foo").get(0)).isType(TypedBeanImpl.class);
@@ -271,7 +271,7 @@ public class ConfigInterfaceTest {
@Test
public void testTypedBean1d3dListMap() throws Exception {
- proxy.setTypedBean1d3dListMap(AMap.of("foo",AList.of(new TypedBean[][][]{{{new TypedBeanImpl().init(),null},null},null},null)));
+ proxy.setTypedBean1d3dListMap(AMap.of("foo",AList.of(new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null},null)));
assertObject(proxy.getTypedBean1d3dListMap()).json().is("{foo:[[[[{_type:'TypedBeanImpl',a:1,b:'foo'},null],null],null],null]}");
assertEquals("{foo:[[[[{_type:'TypedBeanImpl',a:1,b:'foo'},null],null],null],null]}", cf.get("A/typedBean1d3dListMap"));
assertObject(proxy.getTypedBean1d3dListMap().get("foo").get(0)[0][0][0]).isType(TypedBeanImpl.class);
@@ -279,7 +279,7 @@ public class ConfigInterfaceTest {
@Test
public void testTypedBeanListMapIntegerKeys() throws Exception {
- proxy.setTypedBeanListMapIntegerKeys(AMap.of(1,Arrays.asList((TypedBean)new TypedBeanImpl().init())));
+ proxy.setTypedBeanListMapIntegerKeys(AMap.of(1,Arrays.asList((TypedBean)TypedBeanImpl.get())));
assertObject(proxy.getTypedBeanListMapIntegerKeys()).json().is("{'1':[{_type:'TypedBeanImpl',a:1,b:'foo'}]}");
assertEquals("{'1':[{_type:'TypedBeanImpl',a:1,b:'foo'}]}", cf.get("A/typedBeanListMapIntegerKeys"));
assertObject(proxy.getTypedBeanListMapIntegerKeys().get(1).get(0)).isType(TypedBeanImpl.class);
diff --git a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/Constants.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/Constants.java
similarity index 97%
rename from juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/Constants.java
rename to juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/Constants.java
index a0b96a7..b727ffc 100644
--- a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/Constants.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/Constants.java
@@ -10,7 +10,7 @@
// * "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.testutils;
+package org.apache.juneau.testutils;
public class Constants {
diff --git a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/XPartSerializer.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/XPartSerializer.java
similarity index 98%
rename from juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/XPartSerializer.java
rename to juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/XPartSerializer.java
index 8290df2..1373fc5 100644
--- a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/XPartSerializer.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/XPartSerializer.java
@@ -10,7 +10,7 @@
// * "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.testutils;
+package org.apache.juneau.testutils;
import org.apache.juneau.httppart.*;
import org.apache.juneau.serializer.*;
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/ABean.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/ABean.java
index ad0c44e..c55143c 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/ABean.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/ABean.java
@@ -16,9 +16,10 @@ public class ABean {
public int a;
public String b;
- public ABean init() {
- this.a = 1;
- this.b = "foo";
- return this;
+ public static ABean get() {
+ ABean x = new ABean();
+ x.a = 1;
+ x.b = "foo";
+ return x;
}
}
\ No newline at end of file
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/LargePojo.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/LargePojo.java
index 9e1ddd2..efa7a28 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/LargePojo.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/LargePojo.java
@@ -23,7 +23,7 @@ public class LargePojo {
public A1List a1List;
public A1[] a1Array;
- public static LargePojo create() {
+ public static LargePojo get() {
LargePojo a = new LargePojo();
a.a1Map = new A1Map();
a.a1List = new A1List();
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/PrimitiveAtomicObjectsBean.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/PrimitiveAtomicObjectsBean.java
index 208c723..e3625b3 100755
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/PrimitiveAtomicObjectsBean.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/PrimitiveAtomicObjectsBean.java
@@ -48,7 +48,7 @@ public class PrimitiveAtomicObjectsBean {
public List<AtomicInteger[]> polAtomicInteger;
public List<AtomicLong[]> polAtomicLong;
- public PrimitiveAtomicObjectsBean init() {
+ private PrimitiveAtomicObjectsBean init() {
// primitive objects
poAtomicInteger = new AtomicInteger(1);
poAtomicLong = new AtomicLong(2);
@@ -71,4 +71,8 @@ public class PrimitiveAtomicObjectsBean {
return this;
}
+
+ public static PrimitiveAtomicObjectsBean get() {
+ return new PrimitiveAtomicObjectsBean().init();
+ }
}
\ No newline at end of file
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/PrimitiveObjectsBean.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/PrimitiveObjectsBean.java
index 77f1c22..3c4a07e 100755
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/PrimitiveObjectsBean.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/PrimitiveObjectsBean.java
@@ -98,7 +98,7 @@ public class PrimitiveObjectsBean {
public List<BigInteger[]> polBigInteger;
public List<BigDecimal[]> polBigDecimal;
- public PrimitiveObjectsBean init() {
+ private PrimitiveObjectsBean init() {
// primitive objects
poBoolean = true;
poByte = 1;
@@ -175,4 +175,8 @@ public class PrimitiveObjectsBean {
return this;
}
+
+ public static PrimitiveObjectsBean get() {
+ return new PrimitiveObjectsBean().init();
+ }
}
\ No newline at end of file
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/TypedBeanImpl.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/TypedBeanImpl.java
index a78a874..882e602 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/TypedBeanImpl.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/TypedBeanImpl.java
@@ -17,9 +17,13 @@ public class TypedBeanImpl implements TypedBean {
public int a;
public String b;
- public TypedBeanImpl init() {
+ private TypedBeanImpl init() {
this.a = 1;
this.b = "foo";
return this;
}
+
+ public static TypedBeanImpl get() {
+ return new TypedBeanImpl().init();
+ }
}
\ No newline at end of file
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/XBeans.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/XBeans.java
new file mode 100644
index 0000000..9c507a3
--- /dev/null
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/testutils/pojos/XBeans.java
@@ -0,0 +1,263 @@
+// ***************************************************************************************************************************
+// * 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.testutils.pojos;
+
+import java.util.*;
+
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.collections.*;
+import org.apache.juneau.urlencoding.annotation.*;
+
+public class XBeans {
+
+ @Bean(sort=true)
+ public static class XA {
+ public String a;
+ public int b;
+ public boolean c;
+
+ public static XA get() {
+ XA t = new XA();
+ t.a = "a";
+ t.b = 1;
+ t.c = true;
+ return t;
+ }
+
+ }
+
+ @Bean(sort=true)
+ public static class XB {
+ public String[] f01;
+ public List<String> f02;
+ public int[] f03;
+ public List<Integer> f04;
+ public String[][] f05;
+ public List<String[]> f06;
+ public XA[] f07;
+ public List<XA> f08;
+ public XA[][] f09;
+ public List<List<XA>> f10;
+
+ private String[] f11;
+ private List<String> f12;
+ private int[] f13;
+ private List<Integer> f14;
+ private String[][] f15;
+ private List<String[]> f16;
+ private XA[] f17;
+ private List<XA> f18;
+ private XA[][] f19;
+ private List<List<XA>> f20;
+
+ public String[] getF11() { return f11; }
+ public List<String> getF12() { return f12; }
+ public int[] getF13() { return f13; }
+ public List<Integer> getF14() { return f14; }
+ public String[][] getF15() { return f15; }
+ public List<String[]> getF16() { return f16; }
+ public XA[] getF17() { return f17; }
+ public List<XA> getF18() { return f18; }
+ public XA[][] getF19() { return f19; }
+ public List<List<XA>> getF20() { return f20; }
+
+ public void setF11(String[] f11) { this.f11 = f11; }
+ public void setF12(List<String> f12) { this.f12 = f12; }
+ public void setF13(int[] f13) { this.f13 = f13; }
+ public void setF14(List<Integer> f14) { this.f14 = f14; }
+ public void setF15(String[][] f15) { this.f15 = f15; }
+ public void setF16(List<String[]> f16) { this.f16 = f16; }
+ public void setF17(XA[] f17) { this.f17 = f17; }
+ public void setF18(List<XA> f18) { this.f18 = f18; }
+ public void setF19(XA[][] f19) { this.f19 = f19; }
+ public void setF20(List<List<XA>> f20) { this.f20 = f20; }
+
+ public static XB get() {
+ XB t = new XB();
+ t.f01 = new String[]{"a","b"};
+ t.f02 = AList.of("c","d");
+ t.f03 = new int[]{1,2};
+ t.f04 = AList.of(3,4);
+ t.f05 = new String[][]{{"e","f"},{"g","h"}};
+ t.f06 = AList.of(new String[]{"i","j"},new String[]{"k","l"});
+ t.f07 = new XA[]{XA.get(),XA.get()};
+ t.f08 = AList.of(XA.get(),XA.get());
+ t.f09 = new XA[][]{{XA.get()},{XA.get()}};
+ t.f10 = AList.of(Arrays.asList(XA.get()),Arrays.asList(XA.get()));
+ t.setF11(new String[]{"a","b"});
+ t.setF12(AList.of("c","d"));
+ t.setF13(new int[]{1,2});
+ t.setF14(AList.of(3,4));
+ t.setF15(new String[][]{{"e","f"},{"g","h"}});
+ t.setF16(AList.of(new String[]{"i","j"},new String[]{"k","l"}));
+ t.setF17(new XA[]{XA.get(),XA.get()});
+ t.setF18(AList.of(XA.get(),XA.get()));
+ t.setF19(new XA[][]{{XA.get()},{XA.get()}});
+ t.setF20(AList.of(Arrays.asList(XA.get()),Arrays.asList(XA.get())));
+ return t;
+ }
+
+ public static XB INSTANCE = get();
+ }
+
+ @UrlEncoding(expandedParams=true)
+ public static class XC extends XB {
+ public static XC get() {
+ XC t = new XC();
+ t.f01 = new String[]{"a","b"};
+ t.f02 = AList.of("c","d");
+ t.f03 = new int[]{1,2};
+ t.f04 = AList.of(3, 4);
+ t.f05 = new String[][]{{"e","f"},{"g","h"}};
+ t.f06 = AList.of(new String[]{"i","j"}, new String[]{"k","l"});
+ t.f07 = new XA[]{XA.get(),XA.get()};
+ t.f08 = AList.of(XA.get(), XA.get());
+ t.f09 = new XA[][]{{XA.get()},{XA.get()}};
+ t.f10 = AList.of(Arrays.asList(XA.get()), Arrays.asList(XA.get()));
+ t.setF11(new String[]{"a","b"});
+ t.setF12(AList.of("c","d"));
+ t.setF13(new int[]{1,2});
+ t.setF14(AList.of(3,4));
+ t.setF15(new String[][]{{"e","f"},{"g","h"}});
+ t.setF16(AList.of(new String[]{"i","j"},new String[]{"k","l"}));
+ t.setF17(new XA[]{XA.get(),XA.get()});
+ t.setF18(AList.of(XA.get(), XA.get()));
+ t.setF19(new XA[][]{{XA.get()},{XA.get()}});
+ t.setF20(AList.of(Arrays.asList(XA.get()), Arrays.asList(XA.get())));
+ return t;
+ }
+
+ public static XC INSTANCE = get();
+ }
+
+ @BeanConfig(applyBean={@Bean(on="XD,XE,XF",sort=true)})
+ @UrlEncodingConfig(applyUrlEncoding={@UrlEncoding(on="C",expandedParams=true)})
+ public static class Annotations {}
+
+ public static class XD {
+ public String a;
+ public int b;
+ public boolean c;
+
+ public static XD get() {
+ XD t = new XD();
+ t.a = "a";
+ t.b = 1;
+ t.c = true;
+ return t;
+ }
+
+ }
+
+ public static class XE {
+ public String[] f01;
+ public List<String> f02;
+ public int[] f03;
+ public List<Integer> f04;
+ public String[][] f05;
+ public List<String[]> f06;
+ public XD[] f07;
+ public List<XD> f08;
+ public XD[][] f09;
+ public List<List<XD>> f10;
+
+ private String[] f11;
+ private List<String> f12;
+ private int[] f13;
+ private List<Integer> f14;
+ private String[][] f15;
+ private List<String[]> f16;
+ private XD[] f17;
+ private List<XD> f18;
+ private XD[][] f19;
+ private List<List<XD>> f20;
+
+ public String[] getF11() { return f11; }
+ public List<String> getF12() { return f12; }
+ public int[] getF13() { return f13; }
+ public List<Integer> getF14() { return f14; }
+ public String[][] getF15() { return f15; }
+ public List<String[]> getF16() { return f16; }
+ public XD[] getF17() { return f17; }
+ public List<XD> getF18() { return f18; }
+ public XD[][] getF19() { return f19; }
+ public List<List<XD>> getF20() { return f20; }
+
+ public void setF11(String[] f11) { this.f11 = f11; }
+ public void setF12(List<String> f12) { this.f12 = f12; }
+ public void setF13(int[] f13) { this.f13 = f13; }
+ public void setF14(List<Integer> f14) { this.f14 = f14; }
+ public void setF15(String[][] f15) { this.f15 = f15; }
+ public void setF16(List<String[]> f16) { this.f16 = f16; }
+ public void setF17(XD[] f17) { this.f17 = f17; }
+ public void setF18(List<XD> f18) { this.f18 = f18; }
+ public void setF19(XD[][] f19) { this.f19 = f19; }
+ public void setF20(List<List<XD>> f20) { this.f20 = f20; }
+
+ public static XE get() {
+ XE t = new XE();
+ t.f01 = new String[]{"a","b"};
+ t.f02 = AList.of("c","d");
+ t.f03 = new int[]{1,2};
+ t.f04 = AList.of(3,4);
+ t.f05 = new String[][]{{"e","f"},{"g","h"}};
+ t.f06 = AList.of(new String[]{"i","j"},new String[]{"k","l"});
+ t.f07 = new XD[]{XD.get(),XD.get()};
+ t.f08 = AList.of(XD.get(),XD.get());
+ t.f09 = new XD[][]{{XD.get()},{XD.get()}};
+ t.f10 = AList.of(Arrays.asList(XD.get()),Arrays.asList(XD.get()));
+ t.setF11(new String[]{"a","b"});
+ t.setF12(AList.of("c","d"));
+ t.setF13(new int[]{1,2});
+ t.setF14(AList.of(3,4));
+ t.setF15(new String[][]{{"e","f"},{"g","h"}});
+ t.setF16(AList.of(new String[]{"i","j"},new String[]{"k","l"}));
+ t.setF17(new XD[]{XD.get(),XD.get()});
+ t.setF18(AList.of(XD.get(),XD.get()));
+ t.setF19(new XD[][]{{XD.get()},{XD.get()}});
+ t.setF20(AList.of(Arrays.asList(XD.get()),Arrays.asList(XD.get())));
+ return t;
+ }
+
+ public static XE INSTANCE = get();
+ }
+
+ public static class XF extends XE {
+ public static XF get() {
+ XF t = new XF();
+ t.f01 = new String[]{"a","b"};
+ t.f02 = AList.of("c","d");
+ t.f03 = new int[]{1,2};
+ t.f04 = AList.of(3, 4);
+ t.f05 = new String[][]{{"e","f"},{"g","h"}};
+ t.f06 = AList.of(new String[]{"i","j"}, new String[]{"k","l"});
+ t.f07 = new XD[]{XD.get(),XD.get()};
+ t.f08 = AList.of(XD.get(), XD.get());
+ t.f09 = new XD[][]{{XD.get()},{XD.get()}};
+ t.f10 = AList.of(Arrays.asList(XD.get()), Arrays.asList(XD.get()));
+ t.setF11(new String[]{"a","b"});
+ t.setF12(AList.of("c","d"));
+ t.setF13(new int[]{1,2});
+ t.setF14(AList.of(3,4));
+ t.setF15(new String[][]{{"e","f"},{"g","h"}});
+ t.setF16(AList.of(new String[]{"i","j"},new String[]{"k","l"}));
+ t.setF17(new XD[]{XD.get(),XD.get()});
+ t.setF18(AList.of(XD.get(), XD.get()));
+ t.setF19(new XD[][]{{XD.get()},{XD.get()}});
+ t.setF20(AList.of(Arrays.asList(XD.get()), Arrays.asList(XD.get())));
+ return t;
+ }
+
+ public static XF INSTANCE = get();
+ }
+}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderSupplier.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderSupplier.java
index 3094642..94826c3 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderSupplier.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderSupplier.java
@@ -25,6 +25,7 @@ import org.apache.juneau.http.header.*;
import org.apache.juneau.httppart.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.oapi.*;
+import org.apache.juneau.svl.*;
/**
* Specifies a dynamic supplier of {@link Header} objects.
@@ -38,6 +39,8 @@ public class HeaderSupplier implements Iterable<Header> {
private final List<Iterable<Header>> headers = new CopyOnWriteArrayList<>();
+ private volatile VarResolver varResolver;
+
/**
* Convenience creator.
*
@@ -76,12 +79,12 @@ public class HeaderSupplier implements Iterable<Header> {
* @return A new instance.
*/
public static HeaderSupplier ofPairs(Object...parameters) {
- List<Header> l = new ArrayList<>();
+ HeaderSupplier s = HeaderSupplier.create();
if (parameters.length % 2 != 0)
throw new BasicRuntimeException("Odd number of parameters passed into HeaderSupplier.ofPairs()");
for (int i = 0; i < parameters.length; i+=2)
- l.add(new BasicHeader(stringify(parameters[i]), parameters[i+1]));
- return HeaderSupplier.of(l);
+ s.add(stringify(parameters[i]), parameters[i+1]);
+ return s;
}
/**
@@ -110,6 +113,47 @@ public class HeaderSupplier implements Iterable<Header> {
}
/**
+ * Allows header values to contain SVL variables.
+ *
+ * <p>
+ * Resolves variables in header values when using the following methods:
+ * <ul>
+ * <li class='jm'>{@link #ofPairs(Object...) ofPairs(Object...)}
+ * <li class='jm'>{@link #add(String, Object) add(String,Object)}
+ * <li class='jm'>{@link #add(String, Supplier) add(String,Supplier<?>)}
+ * <li class='jm'>{@link #add(String, Object, HttpPartSerializerSession, HttpPartSchema, boolean) add(String,Object,HttpPartSerializerSession,HttpPartSchema,boolean)}
+ * </ul>
+ *
+ * <p>
+ * Uses {@link VarResolver#DEFAULT} to resolve variables.
+ *
+ * @return This object (for method chaining).
+ */
+ public HeaderSupplier resolving() {
+ return resolving(VarResolver.DEFAULT);
+ }
+
+ /**
+ * Allows header values to contain SVL variables.
+ *
+ * <p>
+ * Resolves variables in header values when using the following methods:
+ * <ul>
+ * <li class='jm'>{@link #ofPairs(Object...) ofPairs(Object...)}
+ * <li class='jm'>{@link #add(String, Object) add(String,Object)}
+ * <li class='jm'>{@link #add(String, Supplier) add(String,Supplier<?>)}
+ * <li class='jm'>{@link #add(String, Object, HttpPartSerializerSession, HttpPartSchema, boolean) add(String,Object,HttpPartSerializerSession,HttpPartSchema,boolean)}
+ * </ul>
+ *
+ * @param varResolver The variable resolver to use for resolving variables.
+ * @return This object (for method chaining).
+ */
+ public HeaderSupplier resolving(VarResolver varResolver) {
+ this.varResolver = varResolver;
+ return this;
+ }
+
+ /**
* Add a header to this supplier.
*
* @param h The header to add. <jk>null</jk> values are ignored.
@@ -159,7 +203,7 @@ public class HeaderSupplier implements Iterable<Header> {
* @return This object (for method chaining).
*/
public HeaderSupplier add(String name, Object value) {
- return add(new BasicHeader(name, value));
+ return add(new BasicHeader(name, resolver(value)));
}
/**
@@ -176,7 +220,7 @@ public class HeaderSupplier implements Iterable<Header> {
* @return This object (for method chaining).
*/
public HeaderSupplier add(String name, Supplier<?> value) {
- return add(new BasicHeader(name, value));
+ return add(new BasicHeader(name, resolver(value)));
}
/**
@@ -195,7 +239,7 @@ public class HeaderSupplier implements Iterable<Header> {
* @return This object (for method chaining).
*/
public HeaderSupplier add(String name, Object value, HttpPartSerializerSession serializer, HttpPartSchema schema, boolean skipIfEmpty) {
- return add(new SerializedHeader(name, value, serializer, schema, skipIfEmpty));
+ return add(new SerializedHeader(name, resolver(value), serializer, schema, skipIfEmpty));
}
/**
@@ -244,4 +288,14 @@ public class HeaderSupplier implements Iterable<Header> {
l.add(p);
return l.toArray(array);
}
+
+ private Supplier<Object> resolver(Object input) {
+ return ()->(varResolver == null ? unwrap(input) : varResolver.resolve(stringify(unwrap(input))));
+ }
+
+ private Object unwrap(Object o) {
+ while (o instanceof Supplier)
+ o = ((Supplier<?>)o).get();
+ return o;
+ }
}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/NameValuePairSupplier.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/NameValuePairSupplier.java
index 21be3a5..2367edd 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/NameValuePairSupplier.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/NameValuePairSupplier.java
@@ -24,6 +24,7 @@ import org.apache.juneau.*;
import org.apache.juneau.httppart.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.oapi.*;
+import org.apache.juneau.svl.*;
import org.apache.juneau.urlencoding.*;
/**
@@ -38,6 +39,8 @@ public class NameValuePairSupplier implements Iterable<NameValuePair> {
private final List<Iterable<NameValuePair>> pairs = new CopyOnWriteArrayList<>();
+ private volatile VarResolver varResolver;
+
/**
* Convenience creator.
*
@@ -76,12 +79,12 @@ public class NameValuePairSupplier implements Iterable<NameValuePair> {
* @return A new instance.
*/
public static NameValuePairSupplier ofPairs(Object...parameters) {
- List<NameValuePair> l = new ArrayList<>();
+ NameValuePairSupplier s = NameValuePairSupplier.create();
if (parameters.length % 2 != 0)
throw new BasicRuntimeException("Odd number of parameters passed into NameValuePairSupplier.ofPairs()");
for (int i = 0; i < parameters.length; i+=2)
- l.add(new BasicNameValuePair(stringify(parameters[i]), parameters[i+1]));
- return NameValuePairSupplier.of(l);
+ s.add(stringify(parameters[i]), parameters[i+1]);
+ return s;
}
/**
@@ -110,6 +113,47 @@ public class NameValuePairSupplier implements Iterable<NameValuePair> {
}
/**
+ * Allows values to contain SVL variables.
+ *
+ * <p>
+ * Resolves variables in values when using the following methods:
+ * <ul>
+ * <li class='jm'>{@link #ofPairs(Object...) ofPairs(Object...)}
+ * <li class='jm'>{@link #add(String, Object) add(String,Object)}
+ * <li class='jm'>{@link #add(String, Supplier) add(String,Supplier<?>)}
+ * <li class='jm'>{@link #add(String, Object, HttpPartType, HttpPartSerializerSession, HttpPartSchema, boolean) add(String,Object,HttpPartType,HttpPartSerializerSession,HttpPartSchema,boolean)}
+ * </ul>
+ *
+ * <p>
+ * Uses {@link VarResolver#DEFAULT} to resolve variables.
+ *
+ * @return This object (for method chaining).
+ */
+ public NameValuePairSupplier resolving() {
+ return resolving(VarResolver.DEFAULT);
+ }
+
+ /**
+ * Allows values to contain SVL variables.
+ *
+ * <p>
+ * Resolves variables in values when using the following methods:
+ * <ul>
+ * <li class='jm'>{@link #ofPairs(Object...) ofPairs(Object...)}
+ * <li class='jm'>{@link #add(String, Object) add(String,Object)}
+ * <li class='jm'>{@link #add(String, Supplier) add(String,Supplier<?>)}
+ * <li class='jm'>{@link #add(String, Object, HttpPartType, HttpPartSerializerSession, HttpPartSchema, boolean) add(String,Object,HttpPartType,HttpPartSerializerSession,HttpPartSchema,boolean)}
+ * </ul>
+ *
+ * @param varResolver The variable resolver to use for resolving variables.
+ * @return This object (for method chaining).
+ */
+ public NameValuePairSupplier resolving(VarResolver varResolver) {
+ this.varResolver = varResolver;
+ return this;
+ }
+
+ /**
* Add a name-value pair to this supplier.
*
* @param h The name-value pair to add. <jk>null</jk> values are ignored.
@@ -159,7 +203,7 @@ public class NameValuePairSupplier implements Iterable<NameValuePair> {
* @return This object (for method chaining).
*/
public NameValuePairSupplier add(String name, Object value) {
- return add(new BasicNameValuePair(name, value));
+ return add(new BasicNameValuePair(name, resolver(value)));
}
/**
@@ -176,7 +220,7 @@ public class NameValuePairSupplier implements Iterable<NameValuePair> {
* @return This object (for method chaining).
*/
public NameValuePairSupplier add(String name, Supplier<?> value) {
- return add(new BasicNameValuePair(name, value));
+ return add(new BasicNameValuePair(name, resolver(value)));
}
/**
@@ -199,7 +243,7 @@ public class NameValuePairSupplier implements Iterable<NameValuePair> {
* @return This object (for method chaining).
*/
public NameValuePairSupplier add(String name, Object value, HttpPartType partType, HttpPartSerializerSession serializer, HttpPartSchema schema, boolean skipIfEmpty) {
- return add(new SerializedNameValuePair(name, value, partType, serializer, schema, skipIfEmpty));
+ return add(new SerializedNameValuePair(name, resolver(value), partType, serializer, schema, skipIfEmpty));
}
/**
@@ -248,4 +292,14 @@ public class NameValuePairSupplier implements Iterable<NameValuePair> {
l.add(p);
return l.toArray(array);
}
+
+ private Supplier<Object> resolver(Object input) {
+ return ()->(varResolver == null ? unwrap(input) : varResolver.resolve(stringify(unwrap(input))));
+ }
+
+ private Object unwrap(Object o) {
+ while (o instanceof Supplier)
+ o = ((Supplier<?>)o).get();
+ return o;
+ }
}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/header/BasicHeader.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/header/BasicHeader.java
index b93158b..33fed34 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/header/BasicHeader.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/header/BasicHeader.java
@@ -221,8 +221,8 @@ public class BasicHeader implements Header, Cloneable, Serializable {
* @return The unwrapped object.
*/
protected Object unwrap(Object o) {
- if (o instanceof Supplier)
- return ((Supplier<?>)o).get();
+ while (o instanceof Supplier)
+ o = ((Supplier<?>)o).get();
return o;
}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/Remote.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/Remote.java
index 2df756c..8e99965 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/Remote.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/Remote.java
@@ -42,6 +42,12 @@ public @interface Remote {
* <li>A relative URL interpreted as relative to the root URL defined on the <c>RestClient</c>
* <li>No path interpreted as the class name (e.g. <js>"http://localhost/root-url/org.foo.MyInterface"</js>)
* </ul>
+ *
+ * <ul class='notes'>
+ * <li>
+ * Supports {@doc DefaultSvlVariables}
+ * (e.g. <js>"$P{mySystemProperty}"</js>).
+ * </ul>
*/
String path() default "";
@@ -81,9 +87,9 @@ public @interface Remote {
*
* <p>
* The format of this is a string of the format <c>#[.#[.#[...]]</c> (e.g. <js>"1.2.3"</js>).
- *
+ *
* <p>
- * The server side then uses an OSGi-version matching pattern to identify which methods to call:
+ * The server side then uses an OSGi-version matching pattern to identify which methods to call:
* <p class='bcode w800'>
* <jc>// Call this method if X-Client-Version is at least 2.0.
* // Note that this also matches 2.0.1.</jc>
@@ -98,11 +104,26 @@ public @interface Remote {
* <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"[0,1.1)"</js>)
* <jk>public</jk> Object method3() {...}
* </p>
+ *
+ * <ul class='notes'>
+ * <li>
+ * Supports {@doc DefaultSvlVariables}
+ * (e.g. <js>"$P{mySystemProperty}"</js>).
+ * </ul>
*/
String version() default "";
/**
* Specifies the client version header name.
+ *
+ * <p>
+ * The default value is <js>"X-Client-Version"</js>.
+ *
+ * <ul class='notes'>
+ * <li>
+ * Supports {@doc DefaultSvlVariables}
+ * (e.g. <js>"$P{mySystemProperty}"</js>).
+ * </ul>
*/
- String versionHeader() default "X-Client-Version";
+ String versionHeader() default "";
}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/annotation/Schema.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/annotation/Schema.java
index cf7da9b..c50c859 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/annotation/Schema.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/annotation/Schema.java
@@ -787,12 +787,7 @@ public @interface Schema {
* </p>
* <p class='bcode w800'>
* <jc>// Free-form</jc>
- * <ja>@Schema</ja>(
- * <js>"type: 'array',"</js>,
- * <js>"items: {"</js>,
- * <js>"$ref: '#/definitions/Pet'"</js>,
- * <js>"}"</js>
- * )
+ * <ja>@Schema</ja>(<js>"type:'array',items:{$ref:'#/definitions/Pet'}"</js>)
* </p>
* <p class='bcode w800'>
* <jc>// Free-form using variables</jc>
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/svl/VarResolver.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/svl/VarResolver.java
index 675e5a2..f76b743 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/svl/VarResolver.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/svl/VarResolver.java
@@ -14,6 +14,7 @@ package org.apache.juneau.svl;
import java.io.*;
import java.util.*;
+import java.util.function.*;
import org.apache.juneau.svl.vars.*;
@@ -178,4 +179,14 @@ public class VarResolver {
public void resolveTo(String s, Writer w) throws IOException {
createSession(null).resolveTo(s, w);
}
+
+ /**
+ * Returns a supplier for the specified string.
+ *
+ * @param s The string to resolve.
+ * @return A supplier for the specified string.
+ */
+ public Supplier<String> resolver(String s) {
+ return ()->resolve(s);
+ }
}
\ No newline at end of file
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client.html b/juneau-doc/docs/Topics/09.juneau-rest-client.html
index 87dba6f..9e2ed4a 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client.html
@@ -43,7 +43,7 @@ juneau-rest-client
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Create a basic REST client with JSON support and download a bean.</jc>
- MyBean bean = RestClient.<jsm>create</jsm>()
+ MyBean <jv>bean</jv> = RestClient.<jsm>create</jsm>()
.simpleJson()
.build()
.get(<jsf>URI</jsf>)
@@ -58,17 +58,17 @@ juneau-rest-client
</p>
<p class='bpcode w800'>
- RestClientBuilder builder = RestClient.<jsm>create</jsm>().simpleJson();
- RestClient client = builder.build();
- RestRequest req = client.get(<jsf>URI</jsf>);
- RestResponse res = req.run();
- RestResponseStatusLineAssertion statusLineAssertion = res.assertStatus();
- FluentIntegerAssertion<RestResponse> codeAssertion = statusLineAssertion.code();
- res = codeAssertion.is(200);
- FluentStringAssertion<RestResponse> headerAssertion = res.assertHeader(<js>"Content-Type"</js>);
- res = headerAssertion.matchesSimple(<js>"application/json*"</js>);
- RestResponseBody body = res.getBody();
- MyBean bean = body.as(MyBean.<jk>class</jk>);
+ RestClientBuilder <jv>builder</jv> = RestClient.<jsm>create</jsm>().simpleJson();
+ RestClient <jv>client</jv> = <jv>builder</jv>.build();
+ RestRequest <jv>req</jv> = <jv>client</jv>.get(<jsf>URI</jsf>);
+ RestResponse <jv>res</jv> = <jv>req</jv>.run();
+ RestResponseStatusLineAssertion <jv>statusLineAssertion</jv> = <jv>res</jv>.assertStatus();
+ FluentIntegerAssertion<RestResponse> <jv>codeAssertion</jv> = <jv>statusLineAssertion</jv>.code();
+ <jv>res</jv> = <jv>codeAssertion</jv>.is(200);
+ FluentStringAssertion<RestResponse> <jv>headerAssertion</jv> = <jv>res</jv>.assertHeader(<js>"Content-Type"</js>);
+ <jv>res</jv> = <jv>headerAssertion</jv>.matchesSimple(<js>"application/json*"</js>);
+ RestResponseBody <jv>body</jv> = <jv>res</jv>.getBody();
+ MyBean <jv>bean</jv> = <jv>body</jv>.as(MyBean.<jk>class</jk>);
</p>
<p>
@@ -83,17 +83,18 @@ juneau-rest-client
<ja>@RemoteMethod</ja>(httpMethod=<jsf>POST</jsf>, path=<js>"/pets"</js>)
Pet addPet(
- <ja>@Body</ja> CreatePet pet,
- <ja>@Header</ja>(<js>"E-Tag"</js>) UUID etag,
- <ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> debug
+ <ja>@Body</ja> CreatePet <jv>pet</jv>,
+ <ja>@Header</ja>(<js>"E-Tag"</js>) UUID <jv>etag</jv>,
+ <ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> <jv>debug</jv>
);
}
<jc>// Use a RestClient with default Simple JSON support.</jc>
- RestClient client = RestClient.<jsm>create</jsm>().simpleJson().build();
- PetStore store = client.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
- CreatePet cp = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
- Pet p = store.addPet(cp, UUID.<jsm>randomUUID</jsm>(), <jk>true</jk>);
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().simpleJson().build();
+
+ PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
+ CreatePet <jv>createPet</jv> = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
+ Pet <jv>pet</jv> = <jv>store</jv>.addPet(<jv>createPet</jv>, UUID.<jsm>randomUUID</jsm>(), <jk>true</jk>);
</p>
<p>
@@ -119,10 +120,10 @@ juneau-rest-client
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Create a client where all URIs are relative to localhost.</jc>
- RestClient client = RestClient.<jsm>create</jsm>().json().rootUri(<js>"http://localhost:10000"</js>).build();
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json().rootUri(<js>"http://localhost:10000"</js>).build();
<jc>// Use relative paths.</jc>
- String body = client.get(<js>"/subpath"</js>).run().getBody().asString();
+ String <jv>body</jv> = <jv>client</jv>.get(<js>"/subpath"</js>).run().getBody().asString();
</p>
<p>
@@ -170,8 +171,8 @@ juneau-rest-client
<p class='bpcode w800'>
<jc>// Consuming the response, so use run().</jc>
- String body = client.get(<jsf>URI</jsf>).run().getBody().asString();
+ String <jv>body</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).run().getBody().asString();
<jc>// Only interested in response status code, so use complete().</jc>
- <jk>int</jk> status = client.get(<jsf>URI</jsf>).complete().getStatusCode();
+ <jk>int</jk> <jv>status</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).complete().getStatusCode();
</p>
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/01.PojoMarshalling.html b/juneau-doc/docs/Topics/09.juneau-rest-client/01.PojoMarshalling.html
index d7d5afc..aae0540 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/01.PojoMarshalling.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/01.PojoMarshalling.html
@@ -55,8 +55,8 @@ POJO Marshalling
</p>
<p>
- When using clients with multiple language support, you must specify the <c>Content-Type</c> header on requests
- with bodies to specify which serializer should be selected.
+ When using clients with multiple language support, the request language is selected by setting the <c>Content-Type</c>
+ request header.
</p>
<p class='bpcode w800'>
<jc>// Create a REST client with support for multiple languages.</jc>
@@ -87,8 +87,8 @@ POJO Marshalling
RestClient <jv>client1</jv> = RestClient.<jsm>create</jsm>().json().sq().ws().build();
<jc>// Same, but using properties.</jc>
- RestClient <jv>client</jv> = RestClient
- .<jsm>create2</jsm>()
+ RestClient <jv>client2</jv> = RestClient
+ .<jsm>create</jsm>()
.json()
.set(<jsf>WSERIALIZER_quoteChar</jsf>, <js>'\''</js>)
.set(<jsf>WSERIALIZER_useWhitespace</jsf>, <jk>true</jk>)
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/02.RequestHeaders.html b/juneau-doc/docs/Topics/09.juneau-rest-client/02.RequestHeaders.html
index e4f9307..8090309 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/02.RequestHeaders.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/02.RequestHeaders.html
@@ -43,6 +43,38 @@ Request Headers
</ul>
</ul>
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client that adds a "Foo: bar" header to every request.</jc>
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().header(<js>"Foo"</js>, <js>"bar"</js>).build();
+
+ <jc>// Or do it on every request.</jc>
+ String <jv>response</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).header(<js>"Foo"</js>, <js>"bar"</js>).run().getBody().asString();
+</p>
+
+<p>
+ {@link oajr.client2.RestClientBuilder#headers(Object...) headers(Object...)} allows you to pass in a variety
+ of header objects, and {@link oajr.client2.RestClientBuilder#headerPairs(Object...) headerPairs(Object...)} allows
+ you to specify several headers in a compact fashion.
+</p>
+
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client that adds a bunch of headers to every request.</jc>
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
+ .headers(
+ AMap.<jsm>of</jsm>(<js>"Foo"</js>,<js>"bar"</js>,<js>"Baz"</js>,<js>"qux"</js>) <jc>// Arbitrary key/value pairs.</jc>
+ BasicStringHeader.<jsm>of</jsm>(<js>"Foo"</js>,<js>"bar"</js>) <jc>// A Header object.</jc>
+ BasicStringHeader.<jsm>of</jsm>(<js>"Foo"</js>,()->getBar()) <jc>// A dynamic Header object.</jc>
+ Accept.<jsm>of</jsm>(<js>"application/json"</js>) <jc>// Predefined Header objects.</jc>
+ HeaderSupplier.<jsm>ofPairs</jsm>(<js>"Foo"</js>,<js>"bar"</js>) <jc>// A dynamically changing list of Header objects.</jc>
+ AList.<jsm>of</jsm>(ContentType.<jsm>of</jsm>(<js>"application/json"</js>)) <jc>// A list of anything else on this list.</jc>
+ )
+ .headerPairs(<js>"Foo"</js>,<js>"bar"</js>,<js>"Baz"</js>,<js>"qux"</js>)
+ .build();
+</p>
+
<p>
Additionally, methods are provided on the client builder and per request for all standard HTTP headers
such as {@link oajr.client2.RestClientBuilder#authorization(Object) authorization(Object)}.
@@ -72,14 +104,14 @@ Request Headers
</p>
<p>
- The {@link oaj.httppart.HttpPartSchema} API allows you to define OpenAPI schemas to POJO data structures on both requests
- and responses.
+ The {@link oaj.httppart.HttpPartSchema} API allows you to define OpenAPI schemas to POJO data structures on request headers.
</p>
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Create a client that adds a header "Foo: bar|baz" to every request.</jc>
- RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>()
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
.header(<js>"Foo"</js>, AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>), <jsf>T_ARRAY_PIPES</jsf>)
.build();
</p>
@@ -92,3 +124,7 @@ Request Headers
<li>Methods that pass in POJOs convert values to strings using the part serializers. Methods that pass in <c>Header</c> or
<c>NameValuePair</c> objects use the values returned by that bean directly.
</ul>
+<ul class='seealso'>
+ <li class='jp'>{@link oaj.http.header} - Predefined {@link org.apache.http.Header} beans.
+</ul>
+
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/03.RequestQueryParameters.html b/juneau-doc/docs/Topics/09.juneau-rest-client/03.RequestQueryParameters.html
index 0fa83fe..c72668c 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/03.RequestQueryParameters.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/03.RequestQueryParameters.html
@@ -49,8 +49,47 @@ Request Query Parameters
String <jv>response</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).query(<js>"foo"</js>, <js>"bar"</js>).run().getBody().asString();
</p>
+<p>
+ {@link oajr.client2.RestClientBuilder#queries(Object...) queries(Object...)} allows you to pass in a variety
+ of query parameter objects, and {@link oajr.client2.RestClientBuilder#queryPairs(Object...) queryPairs(Object...)} allows
+ you to specify several query parameters in a compact fashion.
+</p>
+
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client that adds a bunch of query parameters to every request.</jc>
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
+ .queries(
+ AMap.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>,<js>"baz"</js>,<js>"qux"</js>) <jc>// Arbitrary key/value pairs.</jc>
+ BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>) <jc>// A NameValuePair object.</jc>
+ BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>,()->getBar()) <jc>// A dynamic NameValuePair object.</jc>
+ NameValuePairSupplier.<jsm>ofPairs</jsm>(<js>"foo"</js>,<js>"bar"</js>) <jc>// A dynamically changing list of NameValuePair objects.</jc>
+ AList.<jsm>of</jsm>(BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>)) <jc>// A list of anything else on this list.</jc>
+ )
+ .queryPairs(<js>"foo"</js>,<js>"bar"</js>,<js>"baz"</js>,<js>"qux"</js>)
+ .build();
+</p>
+
+<p>
+ The {@link oaj.httppart.HttpPartSchema} API allows you to define OpenAPI schemas to POJO data structures on query parameters.
+</p>
+
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client that adds a query parameter "foo=bar|baz" to every request.</jc>
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
+ .query(<js>"foo"</js>, AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>), <jsf>T_ARRAY_PIPES</jsf>)
+ .build();
+</p>
+
+<p>
+ The methods with {@link oaj.AddFlag} parameters allow you to control whether new query parameters get appended, prepended, or
+ replace existing query parameters with the same name.
+</p>
+
<ul class='notes'>
- <li>Like header values, dynamic values and OpenAPI schemas are supported.
<li>Methods that pass in POJOs convert values to strings using the part serializers. Methods that pass in <c>NameValuePair</c>
objects use the values returned by that bean directly.
</ul>
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/04.RequestFormData.html b/juneau-doc/docs/Topics/09.juneau-rest-client/04.RequestFormData.html
index a7ed7f8..45aa0f8 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/04.RequestFormData.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/04.RequestFormData.html
@@ -40,6 +40,55 @@ Request Form Data
</ul>
</ul>
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client that adds a foo=bar form-data parameter to every request.</jc>
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().formData(<js>"foo"</js>, <js>"bar"</js>).build();
+
+ <jc>// Or do it on every request.</jc>
+ String <jv>response</jv> = <jv>client</jv>.formPost(<jsf>URI</jsf>).formData(<js>"foo"</js>, <js>"bar"</js>).run().getBody().asString();
+</p>
+
+<p>
+ {@link oajr.client2.RestClientBuilder#formDatas(Object...) formDatas(Object...)} allows you to pass in a variety
+ of form-data parameter objects, and {@link oajr.client2.RestClientBuilder#formDataPairs(Object...) formDataPairs(Object...)} allows
+ you to specify several form-data parameters in a compact fashion.
+</p>
+
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client that adds a bunch of form-data parameters to every request.</jc>
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
+ .formDatas(
+ AMap.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>,<js>"baz"</js>,<js>"qux"</js>) <jc>// Arbitrary key/value pairs.</jc>
+ BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>) <jc>// A NameValuePair object.</jc>
+ BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>,()->getBar()) <jc>// A dynamic NameValuePair object.</jc>
+ NameValuePairSupplier.<jsm>ofPairs</jsm>(<js>"foo"</js>,<js>"bar"</js>) <jc>// A dynamically changing list of NameValuePair objects.</jc>
+ AList.<jsm>of</jsm>(BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>)) <jc>// A list of anything else on this list.</jc>
+ )
+ .formDataPairs(<js>"foo"</js>,<js>"bar"</js>,<js>"baz"</js>,<js>"qux"</js>)
+ .build();
+</p>
+
+<p>
+ The {@link oaj.httppart.HttpPartSchema} API allows you to define OpenAPI schemas to POJO data structures on form-data parameters.
+</p>
+
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client that adds a form-data parameter "foo=bar|baz" to every request.</jc>
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
+ .formData(<js>"foo"</js>, AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>), <jsf>T_ARRAY_PIPES</jsf>)
+ .build();
+</p>
+
+<p>
+ The methods with {@link oaj.AddFlag} parameters allow you to control whether new form-data parameters get appended, prepended, or
+ replace existing form-data parameters with the same name.
+</p>
+
<ul class='notes'>
<li>Like header values, dynamic values and OpenAPI schemas are supported.
<li>Methods that pass in POJOs convert values to strings using the part serializers. Methods that pass in <c>NameValuePair</c>
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/05.RequestBody.html b/juneau-doc/docs/Topics/09.juneau-rest-client/05.RequestBody.html
index ea9274b..5e1602d 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/05.RequestBody.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/05.RequestBody.html
@@ -50,6 +50,33 @@ Request Body
{@link java.util.function.Supplier} - A supplier of anything on this list.
</ul>
+<h5 class='figure'>Examples:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client with Simple-JSON support.</jc>
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().simpleJson().build();
+
+ <jc>// Post a JSON-serialized bean.</jc>
+ <jv>client</jv>
+ .post(<jsf>URI</jsf>)
+ .body(<jv>bean</jv>)
+ .complete()
+ .assertStatus().code().is(200);
+
+ <jc>// Post contents from a reader.</jc>
+ <jv>client</jv>
+ .post(<jsf>URI</jsf>)
+ .body(<jk>new</jk> FileReader(<js>"/tmp/foo.json"</js>))
+ .complete()
+ .assertStatus().code().is(200);
+
+ <jc>// Post contents from an Apache HttpEntity object.</jc>
+ <jv>client</jv>
+ .post(<jsf>URI</jsf>)
+ .body(<jk>new</jk> StringEntity(<jv>jsonString</jv>, ContentType.<jsf>APPLICATION_JSON</jsf>))
+ .complete()
+ .assertStatus().code().is(200);
+</p>
+
<ul class='notes'>
<li>If the serializer on the client or request is explicitly set to <jk>null</jk>, POJOs will be converted to strings
using the registered part serializer as content type <js>"text/plain</js>. If the part serializer is also <jk>null</jk>,
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/08.ResponseBody.html b/juneau-doc/docs/Topics/09.juneau-rest-client/08.ResponseBody.html
index cb27f86..451e3b6 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/08.ResponseBody.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/08.ResponseBody.html
@@ -54,10 +54,14 @@ Response Body
</ul>
</ul>
-<br>
-
<h5 class='figure'>Examples:</h5>
<p class='bpcode w800'>
+ <jc>// Parse into a bean.</jc>
+ MyBean <jv>bean</jv> = <jv>client</jv>
+ .get(<jsf>URI</jsf>)
+ .run()
+ .getBody().as(MyBean.<jk>class</jk>);
+
<jc>// Parse into a linked-list of strings.</jc>
List<String> <jv>l1</jv> = <jv>client</jv>
.get(<jsf>URI</jsf>)
@@ -120,8 +124,6 @@ Response Body
</ul>
</ul>
-<br>
-
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Assert that the body contains the string "Success".</jc>
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/09.CustomCallHandlers.html b/juneau-doc/docs/Topics/09.juneau-rest-client/09.CustomCallHandlers.html
index bde12a5..18ec529 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/09.CustomCallHandlers.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/09.CustomCallHandlers.html
@@ -32,6 +32,35 @@ Custom Call Handlers
</ul>
</ul>
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Our custom call handler.</jc>
+ <jk>public class</jk> MyRestCallHandler <jk>implements</jk> RestCallHandler {
+
+ <jk>private final</jk> RestClient <jf>client</jf>;
+
+ <jk>public</jk> MyRestCallHandler(RestClient <jv>client</jv>) {
+ <jk>this</jk>.<jf>client</jf> = <jv>client</jv>;
+ }
+
+ <ja>@Override</ja>
+ <jk>public</jk> HttpResponse run(HttpHost <jv>target</jv>, HttpRequest <jv>request</jv>, HttpContext <jv>context</jv>) <jk>throws</jk> IOException {
+ <jc>// Insert any special handling here.</jc>
+ <jc>// The following is the default behavior:</jc>
+ <jk>if</jk> (<jv>target</jv> == <jk>null</jk>)
+ <jk>return</jk> <jf>client</jf>.execute((HttpUriRequest)<jv>request</jv>, <jv>context</jv>);
+ <jk>return</jk> <jf>client</jf>.execute(<jv>target</jv>, <jv>request</jv>, <jv>context</jv>);
+ }
+ }
+
+ <jc>// Create a client that uses our custom handler.</jc>
+ RestClient <jv>client</jv> = RestClient()
+ .create()
+ .json()
+ .callHandler(MyCallHandler.<jk>class</jk>)
+ .build();
+</p>
+
<p>
Note that there are other ways of accomplishing this such as extending the {@link oajr.client2.RestClient} class and overriding
the {@link oaj.rest.client2.RestClient#run(HttpHost,HttpRequest,HttpContext)} method
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/10.Interceptors.html b/juneau-doc/docs/Topics/09.juneau-rest-client/10.Interceptors.html
index 9404207..eb201c5 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/10.Interceptors.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/10.Interceptors.html
@@ -1,15 +1,15 @@
<!--
/***************************************************************************************************************************
- * 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.
+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.
***************************************************************************************************************************/
-->
@@ -37,3 +37,32 @@ Interceptors
<li class='jm'>{@link oajr.client2.RestCallInterceptor#onClose(RestRequest,RestResponse) onClose(RestRequest,RestResponse)}
</ul>
</ul>
+
+<h5 class='section'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client with a customized interceptor.</jc>
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
+ .interceptors(
+ <jk>new</jk> RestCallInterceptor() {
+
+ <ja>@Override</ja>
+ <jk>public void</jk> onInit(RestRequest <jv>req</jv>) <jk>throws</jk> Exception {
+ <jc>// Intercept immediately after RestRequest object is created and all headers/query/form-data has been
+ // set on the request from the client.</jc>
+ }
+
+ <ja>@Override</ja>
+ <jk>public void</jk> onConnect(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> Exception {
+ <jc>// Intercept immediately after an HTTP response has been received.</jc>
+ }
+
+ <ja>@Override</ja>
+ <jk>public void</jk> onClose(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> Exception {
+ <jc>// Intercept when the response body is consumed.</jc>
+ }
+ }
+ )
+ .build();
+</p>
+
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies.html b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies.html
index d163f3d..4751779 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies.html
@@ -13,34 +13,12 @@
***************************************************************************************************************************/
-->
-{8.1.4-new}
+{8.1.4-updated}
REST Proxies
<p>
One of the more powerful features of the REST client class is the ability to produce Java interface proxies against
- arbitrary remote REST resources.
-</p>
-
-<h5 class='figure'>Example:</h5>
-<p class='bpcode w800'>
- <jc>// Define a Remote proxy for interacting with a REST interface.</jc>
- <ja>@Remote</ja>(path=<js>"/petstore"</js>)
-
- <jk>public interface</jk> PetStore {
- <ja>@RemoteMethod</ja>(httpMethod=<jsf>POST</jsf>, path=<js>"/pets"</js>)
- Pet addPet(
- <ja>@Body</ja> CreatePet <jv>pet</jv>,
- <ja>@Header</ja>(<js>"E-Tag"</js>) UUID <jv>etag</jv>,
- <ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> <jv>debug</jv>
- );
- }
-
- <jc>// Use a RestClient with default Simple JSON support.</jc>
- RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().simpleJson().build()) {
-
- PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
- CreatePet <jv>createPet</jv> = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
- Pet <jv>pet</jv> = <jv>store</jv>.addPet(<jv>createPet</jv>, UUID.<jsm>randomUUID</jsm>(), <jk>true</jk>);
+ arbitrary 3rd party REST resources.
</p>
<p>
@@ -53,47 +31,10 @@ REST Proxies
<li class='jm'><c>{@link oajr.client2.RestClient#getRemote(Class) getRemote(Class<T>)} <jk>returns</jk> T</c>
<li class='jm'><c>{@link oajr.client2.RestClient#getRemote(Class,Object) getRemote(Class<T>,Object)} <jk>returns</jk> T</c>
<li class='jm'><c>{@link oajr.client2.RestClient#getRemote(Class,Object,Serializer,Parser) getRemote(Class<T>,Object,Serializer,Parser)} <jk>returns</jk> T</c>
- <li class='jm'><c>{@link oajr.client2.RestClient#getRrpcInterface(Class) getRrpcInterface(Class<T>)} <jk>returns</jk> T</c>
- <li class='jm'><c>{@link oajr.client2.RestClient#getRrpcInterface(Class,Object) getRrpcInterface(Class<T>,Object)} <jk>returns</jk> T</c>
- <li class='jm'><c>{@link oajr.client2.RestClient#getRrpcInterface(Class,Object,Serializer,Parser) getRrpcInterface(Class<T>,Object,Serializer,Parser)} <jk>returns</jk> T</c>
</ul>
</ul>
<p>
- Two basic types of remote interfaces are provided:
-</p>
-
-<ul class='spaced-list'>
- <li>{@link oaj.http.remote.Remote @Remote}-annotated interfaces. These can be defined against arbitrary external REST resources.
- <li>RPC-over-REST interfaces. These are Java interfaces that allow you to make method calls on server-side POJOs.
-</ul>
-
-
-
-
-
-
-
-
-
-
-<p>
- The <c>juneau-rest-client</c> library can also be used to define interface proxies against 3rd-party REST interfaces.
- This is an extremely powerful feature that allows you to quickly define easy-to-use interfaces against
- virtually any REST interface.
-</p>
-<p>
- Remote resources are instantiated using one of the following methods:
-</p>
-<ul class='javatree'>
- <li class='jc'>{@link oajr.client2.RestClient}
- <ul>
- <li class='jm'>{@link oajr.client2.RestClient#getRemote(Class) getRemote(Class)}
- <li class='jm'>{@link oajr.client2.RestClient#getRemote(Class,Object) getRemote(Class,Object)}
- <li class='jm'>{@link oajr.client2.RestClient#getRemote(Class,Object,Serializer,Parser) getRemote(Class,Object,Serializer,Parser)}
- </ul>
-</ul>
-<p>
Annotations are used on the interface and interface methods to specify how to convert input and output to HTTP headers, query parameters, form
post parameters, or request/response bodies.
</p>
@@ -121,24 +62,30 @@ REST Proxies
<jk>public interface</jk> PetStore {
<ja>@RemoteMethod</ja>(method=<jsf>POST</jsf>, path=<js>"/pets"</js>)
- String addPet(
- <ja>@Body</ja> CreatePet pet,
- <ja>@Header</ja>(<js>"E-Tag"</js>) UUID etag,
- <ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> debug
+ Pet addPet(
+ <ja>@Body</ja> CreatePet <jv>createPet</jv>,
+ <ja>@Header</ja>(<js>"E-Tag"</js>) UUID <jv>etag</jv>,
+ <ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> <jv>debug</jv>
);
}
</p>
+
<p class='bpcode w800'>
<jc>// Use a RestClient with default Simple JSON support.</jc>
- <jk>try</jk> (RestClient client = RestClient.<jsm>create</jsm>().simpleJson().build()) {
- PetStore store = client.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
- CreatePet pet = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
- String response = store.createPet(pet, UUID.<jsm>randomUUID</jsm>(), <jk>true</jk>);
- }
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().simpleJson().build();
+
+ <jc>// Instantiate our proxy interface.</jc>
+ PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
+
+ <jc>// Use it to create a pet.</jc>
+ CreatePet <jv>createPet</jv> = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
+ Pet <jv>pet</jv> = <jv>store</jv>.addPet(<jv>createPet</jv>, UUID.<jsm>randomUUID</jsm>(), <jk>true</jk>);
</p>
+
<p>
The call above translates to the following REST call:
</p>
+
<p class='bpcode w800'>
POST http://localhost:10000/petstore/pets?debug=true HTTP/1.1
Accept: application/json
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/01.Remote.html b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/01.Remote.html
index 17a1a55..f50fdf0 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/01.Remote.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/01.Remote.html
@@ -1,31 +1,37 @@
<!--
/***************************************************************************************************************************
- * 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.
+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.
***************************************************************************************************************************/
-->
-{8.1.2-updated}
+{8.1.2-updated,8.1.4-updated}
@Remote
<p>
The {@link oaj.http.remote.Remote @Remote} annotation is used on your interface class
to identify it as a REST proxy interface.
</p>
+
<ul class='javatree'>
<li class='ja'>{@link oaj.http.remote.Remote}
<ul>
<li class='jf'>{@link oaj.http.remote.Remote#path path}
+ <li class='jf'>{@link oaj.http.remote.Remote#headers headers}
+ <li class='jf'>{@link oaj.http.remote.Remote#headerSupplier headerSupplier}
+ <li class='jf'>{@link oaj.http.remote.Remote#version version}
+ <li class='jf'>{@link oaj.http.remote.Remote#versionHeader versionHeader}
</ul>
</ul>
+
<p>
The <ja>@Remote</ja> annotation is optional, but often included for code readability.
</p>
@@ -35,39 +41,137 @@
The {@link oaj.http.remote.Remote#path @Remote(path)} annotation is used to define the
HTTP path of the REST service.
</p>
+
<p>
The path can be an absolute path to your REST service.
</p>
+
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<ja>@Remote</ja>(path=<js>"http://localhost:10000/petstore"</js>)
<jk>public interface</jk> PetStore {...}
</p>
<p class='bpcode w800'>
- PetStore p = client.getRemote(PetStore.<jk>class</jk>);
+ PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>);
+</p>
+
+<p>
+ {@doc DefaultSvlVariables} can also be used in the path.
+</p>
+
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// URL is specified via a system property.</jc>
+ <ja>@Remote</ja>(path=<js>"$P{PetStoreUrl}"</js>)
+ <jk>public interface</jk> PetStore {...}
</p>
+
<p>
When a relative path is specified, it's relative to the root-url defined on the <c>RestClient</c> used to instantiate the interface.
</p>
+
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<ja>@Remote</ja>(path=<js>"/petstore"</js>)
<jk>public interface</jk> PetStore {...}
</p>
<p class='bpcode w800'>
- RestClient client = RestClient.<jsm>create</jsm>().json().rootUrl(<js>"http://localhost:10000"</js>).build();
- PetStore p = client.getRemote(PetStore.<jk>class</jk>);
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
+ .json()
+ .rootUrl(<js>"http://localhost:10000"</js>)
+ .build();
+
+ PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>);
</p>
+
<p>
When no path is specified, the root-url defined on the <c>RestClient</c> is used.
</p>
+
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<ja>@Remote</ja>
<jk>public interface</jk> PetStore {...}
</p>
<p class='bpcode w800'>
- RestClient client = RestClient.<jsm>create</jsm>().json().rootUrl(<js>"http://localhost:10000/petstore"</js>).build();
- PetStore p = client.getRemote(PetStore.<jk>class</jk>);
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
+ .json()
+ .rootUrl(<js>"http://localhost:10000/petstore"</js>)
+ .build();
+
+ PetStore <jv>store</jv> = <jv>client<jv>.getRemote(PetStore.<jk>class</jk>);
+</p>
+
+
+<h5 class='topic'>@Remote(headers/headerSupplier)</h5>
+<p>
+ The {@link oaj.http.remote.Remote#headers @Remote(headers)} and {@link oaj.http.remote.Remote#headerSupplier @Remote(headerSupplier)}
+ annotations are used to add headers on all requests.
+</p>
+
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <ja>@Remote</ja>(
+ path=<js>"/petstore"</js>,
+ headers={
+ <js>"Foo: bar"</js>,
+ <js>"Baz: $P{bazProperty}"</js>
+ },
+ headerSupplier=MyDynamicHeaderSupplier.<jk>class</jk>
+ )
+ <jk>public interface</jk> PetStore {...}
+</p>
+<p class='bpcode w800'>
+ <jc>// Our dynamic supplier.</jc>
+ <jk>public class</jk> MyHeaderSupplier <jk>extends</jk> HeaderSupplier {
+
+ <jc>// Headers can be added here at runtime.</jc>
+ <jk>public static</jk> HeaderSupplier <jsf>DYNAMIC_HEADERS</jsf> = <jk>new</jk> HeaderSupplier();
+
+ <jk>public</jk> MyHeaderSupplier() {
+ add(<js>"Qux"</js>,<js>"q2x"</js>);
+ add(<jsf>DYNAMIC_HEADERS</jsf>);
+ }
+ }
+</p>
+
+
+<h5 class='topic'>@Remote(version/versionHeader)</h5>
+<p>
+ The {@link oaj.http.remote.Remote#version @Remote(version)} and {@link oaj.http.remote.Remote#versionHeader @Remote(versionHeader)}
+ annotations are used to specify the client-side version of this interface that can be used on the server side
+ to perform version-specific handling.
+</p>
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <ja>@Remote</ja>(
+ path=<js>"/petstore"</js>,
+ version=<js>"1.2.3"</js> <jc>// Adds "X-Client-Version: 1.2.3" header to all requests.</jc>
+ )
+ <jk>public interface</jk> PetStore {...}
+</p>
+
+<p>
+ This can be used in conjunction with the server-side client-versioning support.
+</p>
+<p class='bpcode w800'>
+ <jc>// Call this method if X-Client-Version is at least 2.0.
+ // Note that this also matches 2.0.1.</jc>
+ <ja>@RestMethod</ja>(clientVersion=<js>"2.0"</js>)
+ <jk>public</jk> Object getFoo() {...}
+
+ <jc>// Call this method if X-Client-Version is at least 1.1, but less than 2.0.</jc>
+ <ja>@RestMethod</ja>(clientVersion=<js>"[1.1,2.0)"</js>)
+ <jk>public</jk> Object getFoo() {...}
+
+ <jc>// Call this method if X-Client-Version is less than 1.1.</jc>
+ <ja>@RestMethod</ja>(clientVersion=<js>"[0,1.1)"</js>)
+ <jk>public</jk> Object getFoo() {...}
</p>
+<ul class='seealso'>
+ <li class='doclink'>{@doc juneau-rest-server.ClientVersioning}
+</ul>
+
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/02.RemoteMethod.html b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/02.RemoteMethod.html
index d4f9c39..0f500ba 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/02.RemoteMethod.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/02.RemoteMethod.html
@@ -39,7 +39,7 @@
<jc>// GET /pets/{petId}</jc>
<ja>@RemoteMethod</ja>(method=<js>"GET"</js>, path=<js>"/pets/{petId}"</js>)
- Pet getPet(<ja>@Path</ja>(<js>"petId"</js>) <jk>int</jk> id);
+ Pet getPet(<ja>@Path</ja>(<js>"petId"</js>) <jk>int</jk> <jv>id</jv>);
}
</p>
<p>
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/03.Body.html b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/03.Body.html
index edd6fb6..baa4b0b 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/03.Body.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/03.Body.html
@@ -23,7 +23,7 @@
<li class='ja'>{@link oaj.http.annotation.Body}
<ul>
<li class='jf'>{@link oaj.http.annotation.Body#required() required} - Input validation. Body must be present.
- <li class='jf'>{@link oaj.http.annotation.Body#schema() schema} - Swagger schema.
+ <li class='jf'>{@link oaj.http.annotation.Body#schema() schema} - OpenAPI schema.
</ul>
</ul>
@@ -34,7 +34,7 @@
<jk>public interface</jk> PetStore {
<ja>@RemoteMethod</ja>(path=<js>"/pets"</js>)
- String addPet(<ja>@Body</ja> Pet pet);
+ String addPet(<ja>@Body</ja> Pet <jv>pet</jv>;
}
</p>
<p class='bpcode w800'>
@@ -43,7 +43,7 @@
<jk>public interface</jk> PetStore {
<ja>@RemoteMethod</ja>(path=<js>"/pets"</js>)
- String addPet(Pet pet);
+ String addPet(Pet <jv>pet</jv>);
}
<ja>@Body</ja>
@@ -64,7 +64,7 @@
{@link java.io.InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
<br><c>Content-Type</c> is set to <js>"application/octet-stream"</js>.
<li>
- <c>NameValuePairs</c> - Converted to a URL-encoded FORM post.
+ {@link oaj.http.NameValuePairSupplier} - Converted to a URL-encoded FORM post.
<br><c>Content-Type</c> is set to <js>"aplication/x-www-form-urlencoded"</js>.
<li>
<c>HttpEntity</c> - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
@@ -93,7 +93,20 @@
)
)
)
- <jk>int</jk>[][] input
+ <jk>int</jk>[][] <jv>input</jv>
+ );
+</p>
+<p class='bpcode w800'>
+ <jc>// Same as above but using free-form schema.</jc>
+ <ja>@RemoteMethod</ja>(path=<js>"/comma-delimited-pipe-delimited-ints"</js>)
+ String addCommaDelimitedPipeDelimitedInts(
+ <ja>@Body</ja>(
+ serializer=OpenApiSerializer.<jk>class</jk>,
+ schema=<ja>@Schema</ja>(
+ <js>"type:'array,collectionFormat:'pipes',items:[type:'array',items:[type:'int32',minimum:0,maximum:64]]"</js>
+ )
+ )
+ <jk>int</jk>[][] <jv>input</jv>
);
</p>
<p>
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/04.FormData.html b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/04.FormData.html
index a813e80..9a43d5c 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/04.FormData.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/04.FormData.html
@@ -55,30 +55,30 @@
<jc>// Explicit names specified for form data parameters.</jc>
<ja>@RemoteMethod</ja>
String postParameters(
- <ja>@FormData</ja>(<js>"foo"</js>)</ja> String foo,
- <ja>@FormData</ja>(<js>"bar"</js>)</ja> MyPojo pojo
+ <ja>@FormData</ja>(<js>"foo"</js>)</ja> String <jv>foo</jv>,
+ <ja>@FormData</ja>(<js>"bar"</js>)</ja> MyPojo <jv>pojo</jv>
);
- <jc>// Multiple values pulled from a NameValuePairs object.</jc>
+ <jc>// Multiple values pulled from a NameValuePairSupplier object.</jc>
<jc>// Name "*" is inferred.</jc>
<ja>@RemoteMethod</ja>
- String postNameValuePairs(<ja>@FormData</ja> NameValuePairs nameValuePairs);
+ String postNameValuePairs(<ja>@FormData</ja> NameValuePairSupplier <jv>nameValuePairSupplier</jv>);
<jc>// Multiple values pulled from a Map.</jc>
<ja>@RemoteMethod</ja>
- String postMap(<ja>@FormData</ja> Map<String,Object> map);
+ String postMap(<ja>@FormData</ja> Map<String,Object> <jv>map</jv>);
<jc>// Multiple values pulled from a bean.</jc>
<ja>@RemoteMethod</ja>
- String postBean(<ja>@FormData</ja> MyBean bean);
+ String postBean(<ja>@FormData</ja> MyBean <jv>bean</jv>);
<jc>// An entire form-data HTTP body as a String.</jc>
<ja>@RemoteMethod</ja>
- String postString(<ja>@FormData</ja> String string);
+ String postString(<ja>@FormData</ja> String <jv>string</jv>);
<jc>// An entire form-data HTTP body as a Reader.</jc>
<ja>@RemoteMethod</ja>
- String postReader(<ja>@FormData</ja> Reader reader);
+ String postReader(<ja>@FormData</ja> Reader <jv>reader</jv>);
}
</p>
@@ -99,7 +99,7 @@
<li>
{@link java.io.InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
<li>
- <c>NameValuePairs</c> - Converted to a URL-encoded FORM post.
+ {@link oaj.http.NameValuePairSupplier} - Converted to a URL-encoded FORM post.
<li>
<c>Map</c> - Converted to key-value pairs.
<br>Values serialized using the registered {@link oaj.httppart.HttpPartSerializer} ({@link oaj.oapi.OpenApiSerializer} by default).
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/05.Query.html b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/05.Query.html
index c152440..1f4325c 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/05.Query.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/05.Query.html
@@ -55,33 +55,33 @@
<jc>// Explicit names specified for query parameters.</jc>
<ja>@RemoteMethod</ja>
String parameters(
- <ja>@Query</ja>(<js>"foo"</js>)</ja> String foo,
- <ja>@Query</ja>(<js>"bar"</js>)</ja> MyPojo pojo);
+ <ja>@Query</ja>(<js>"foo"</js>)</ja> String <jv>foo</jv>,
+ <ja>@Query</ja>(<js>"bar"</js>)</ja> MyPojo <jv>pojo</jv>);
- <jc>// Multiple values pulled from a NameValuePairs object.</jc>
+ <jc>// Multiple values pulled from a NameValuePairSupplier object.</jc>
<jc>// Same as @Query("*").</jc>
<ja>@RemoteMethod</ja>
- String nameValuePairs(<ja>@Query</ja> NameValuePairs nameValuePairs);
+ String nameValuePairs(<ja>@Query</ja> NameValuePairSupplier <jv>nameValuePairSupplier</jv>);
<jc>// Multiple values pulled from a Map.</jc>
<jc>// Same as @Query("*").</jc>
<ja>@RemoteMethod</ja>
- String map(<ja>@Query</ja> Map<String,Object> map);
+ String map(<ja>@Query</ja> Map<String,Object> <jv>map</jv>);
<jc>// Multiple values pulled from a bean.</jc>
<jc>// Same as @Query("*").</jc>
<ja>@RemoteMethod</ja>
- String bean(<ja>@Query</ja> MyBean myBean);
+ String bean(<ja>@Query</ja> MyBean <jv>myBean</jv>);
<jc>// An entire query string as a String.</jc>
<jc>// Same as @Query("*").</jc>
<ja>@RemoteMethod</ja>
- String string(<ja>@Query</ja> String string);
+ String string(<ja>@Query</ja> String <jv>string</jv>);
<jc>// An entire query string as a Reader.</jc>
<jc>// Same as @Query("*").</jc>
<ja>@RemoteMethod</ja>
- String reader(<ja>@Query</ja> Reader reader);
+ String reader(<ja>@Query</ja> Reader <jv>reader</jv>);
}
</p>
@@ -101,7 +101,7 @@
<li>
{@link java.io.Reader} - Raw contents of {@code Reader} will be serialized directly a query string.
<li>
- <c>NameValuePairs</c> - Serialized as individual query parameters.
+ {@link oaj.http.NameValuePairSupplier} - Serialized as individual query parameters.
<li>
<c>Map</c> - Converted to key-value pairs.
<br>Values serialized using the registered {@link oaj.httppart.HttpPartSerializer} ({@link oaj.oapi.OpenApiSerializer} by default).
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/06.Header.html b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/06.Header.html
index 72bba67..ea8f6dd 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/06.Header.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/06.Header.html
@@ -55,23 +55,23 @@
<jc>// Explicit names specified for HTTP headers.</jc>
<jc>// pojo will be converted to UON notation (unless plain-text parts enabled).</jc>
<ja>@RemoteMethod</ja>(path=<js>"/mymethod1"</js>)
- String myProxyMethod1(<ja>@Header</ja>(<js>"Foo"</js>)</ja> String foo,
- <ja>@Header</ja>(<js>"Bar"</js>)</ja> MyPojo pojo);
+ String myProxyMethod1(<ja>@Header</ja>(<js>"Foo"</js>)</ja> String <jv>foo</jv>,
+ <ja>@Header</ja>(<js>"Bar"</js>)</ja> MyPojo <jv>pojo</jv>);
- <jc>// Multiple values pulled from a NameValuePairs object.</jc>
+ <jc>// Multiple values pulled from a HeaderSupplier object.</jc>
<jc>// Same as @Header("*").</jc>
<ja>@RemoteMethod</ja>(path=<js>"/mymethod2"</js>)
- String myProxyMethod2(<ja>@Header</ja> NameValuePairs nameValuePairs);
+ String myProxyMethod2(<ja>@Header</ja> HeaderSupplier <jv>headerSupplier</jv>);
<jc>// Multiple values pulled from a Map.</jc>
<jc>// Same as @Header("*").</jc>
<ja>@RemoteMethod</ja>(path=<js>"/mymethod3"</js>)
- String myProxyMethod3(<ja>@Header</ja> Map<String,Object> map);
+ String myProxyMethod3(<ja>@Header</ja> Map<String,Object> <jv>map</jv>);
<jc>// Multiple values pulled from a bean.</jc>
<jc>// Same as @Header("*").</jc>
<ja>@RemoteMethod</ja>(path=<js>"/mymethod4"</js>)
- String myProxyMethod4(<ja>@Header</ja> MyBean myBean);
+ String myProxyMethod4(<ja>@Header</ja> MyBean <jv>myBean</jv>);
}
</p>
@@ -89,7 +89,7 @@
</p>
<ul class='spaced-list'>
<li>
- <c>NameValuePairs</c> - Serialized as individual headers.
+ {@link oaj.http.HeaderSupplier} - Serialized as individual headers.
<li>
<c>Map</c> - Converted to key-value pairs.
<br>Values serialized using the registered {@link oaj.httppart.HttpPartSerializer} ({@link oaj.oapi.OpenApiSerializer} by default).
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/07.Path.html b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/07.Path.html
index 2f226b6..93c1c5f 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/07.Path.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/07.Path.html
@@ -49,22 +49,22 @@
<jc>// Explicit names specified for path parameters.</jc>
<jc>// pojo will be converted to UON notation (unless plain-text parts enabled).</jc>
<ja>@RemoteMethod</ja>(path=<js>"/mymethod1/{foo}/{bar}"</js>)
- String myProxyMethod1(<ja>@Path</ja>(<js>"foo"</js>)</ja> String foo, <ja>@Path</ja>(<js>"bar"</js>)</ja> MyPojo pojo);
+ String myProxyMethod1(<ja>@Path</ja>(<js>"foo"</js>)</ja> String <jv>foo</jv>, <ja>@Path</ja>(<js>"bar"</js>)</ja> MyPojo <jv>pojo</jv>);
- <jc>// Multiple values pulled from a NameValuePairs object.</jc>
+ <jc>// Multiple values pulled from a NameValuePairSupplier object.</jc>
<jc>// Same as @Path("*").</jc>
<ja>@RemoteMethod</ja>(path=<js>"/mymethod2/{foo}/{bar}/{baz}"</js>)
- String myProxyMethod2(<ja>@Path</ja> NameValuePairs nameValuePairs);
+ String myProxyMethod2(<ja>@Path</ja> NameValuePairSupplier <jv>nameValuePairSupplier</jv>);
<jc>// Multiple values pulled from a Map.</jc>
<jc>// Same as @Path("*").</jc>
<ja>@RemoteMethod</ja>(path=<js>"/mymethod3/{foo}/{bar}/{baz}"</js>)
- String myProxyMethod3(<ja>@Path</ja> Map<String,Object> map);
+ String myProxyMethod3(<ja>@Path</ja> Map<String,Object> <jv>map</jv>);
<jc>// Multiple values pulled from a bean.</jc>
<jc>// Same as @Path("*").</jc>
<ja>@RemoteMethod</ja>(path=<js>"/mymethod4/{foo}/{bar}/{baz}"</js>)
- String myProxyMethod4(<ja>@Path</ja> MyBean myBean);
+ String myProxyMethod4(<ja>@Path</ja> MyBean <jv>myBean</jv>);
}
</p>
@@ -82,7 +82,7 @@
</p>
<ul class='spaced-list'>
<li>
- <c>NameValuePairs</c> - Serialized as individual query parameters.
+ {@link oaj.http.NameValuePairSupplier} - Serialized as individual path parameters.
<li>
<c>Map</c> - Converted to key-value pairs.
<br>Values serialized using the registered {@link oaj.httppart.HttpPartSerializer} ({@link oaj.oapi.OpenApiSerializer} by default).
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/08.Request.html b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/08.Request.html
index e293d1d..a8279ea 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/08.Request.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/08.Request.html
@@ -34,7 +34,7 @@
<jk>public interface</jk> PetStore {
<ja>@RemoteMethod</ja>
- String postPet(CreatePetRequest bean);
+ String postPet(CreatePetRequest <jv>bean</jv>);
}
</p>
<p class='bpcode w800'>
@@ -43,8 +43,8 @@
<jk>private</jk> CreatePet <jf>pet</jf>;
- <jk>public</jk> CreatePetRequest(String name, <jk>float</jk> price) {
- <jk>this</jk>.<jf>pet</jf> = <jk>new</jk> CreatePet(name, price);
+ <jk>public</jk> CreatePetRequest(String <jv>name</jv>, <jk>float</jk> <jv>price</jv>) {
+ <jk>this</jk>.<jf>pet</jf> = <jk>new</jk> CreatePet(<jv>name</jv>, <jv>price</jv>);
}
<ja>@Body</ja>
@@ -54,7 +54,7 @@
<ja>@Query</ja>
<jk>public</jk> Map<String,Object> getQueryParams() {
- <jk>return</jk> OMap.<jsm>of</jsm>(<js>"debug"</js>, <jk>true</jk>);
+ <jk>return</jk> AMap.<jsm>of</jsm>(<js>"debug"</js>, <jk>true</jk>);
}
<ja>@Header</ja>(<js>"E-Tag"</js>)
@@ -64,9 +64,10 @@
}
</p>
<p class='bpcode w800'>
- PetStore store = restClient.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
- CreatePetRequest requestBean = <jk>new</jk> CreatePetRequest(<js>"Fluffy"</js>, 9.99);
- String response = store.postPet(requestBean);
+ PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
+
+ CreatePetRequest <jv>requestBean</jv> = <jk>new</jk> CreatePetRequest(<js>"Fluffy"</js>, 9.99);
+ String <jv>response</jv> = <jv>store</jv>.postPet(requestBean);
</p>
<p>
The <ja>@Request</ja> annotation can be applied to either the class or argument.
@@ -110,7 +111,7 @@
<p class='bpcode w800'>
<jk>public class</jk> CreatePetRequestImpl <jk>implements</jk> CreatePetRequest {
- <jk>public</jk> CreatePetRequestImpl(String name, <jk>float</jk> price) {...}
+ <jk>public</jk> CreatePetRequestImpl(String <jv>name</jv>, <jk>float</jk> <jv>price</jv>) {...}
<ja>@Override</ja>
<jk>public</jk> CreatePet getBody() {
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/09.Response.html b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/09.Response.html
index 3091286..466cea3 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/09.Response.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/09.Response.html
@@ -47,15 +47,16 @@
UUID getUUID();
<ja>@ResponseStatus</ja>
- int getStatus();
+ <jk>int</jk> getStatus();
}
</p>
<p class='bpcode w800'>
- PetStore store = restClient.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
- CreatePetResponse response = store.postPet(...);
- Pet pet = response.getBody();
- UUID uuid = response.getUUID();
- <jk>int</jk> status = response.getStatus();
+ PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
+
+ CreatePetResponse <jv>response</jv> = <jv>store</jv>.postPet(...);
+ Pet <jv>pet</jv> = <jv>response</jv>.getBody();
+ UUID <jv>uuid</jv> = <jv>response</jv>.getUUID();
+ <jk>int</jk> <jv>status</jv> = <jv>response</jv>.getStatus();
</p>
<p>
The annotated methods must be no-arg.
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/10.DualPurposeInterfaces.html b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/10.DualPurposeInterfaces.html
index cf1f937..830aaf7 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/10.DualPurposeInterfaces.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/11.RestProxies/10.DualPurposeInterfaces.html
@@ -46,13 +46,13 @@ Dual-purpose (end-to-end) interfaces
required=<jk>true</jk>,
example=<js>"foobar"</js>
)
- String apiKey,
+ String <jv>apiKey</jv>,
<ja>@Path</ja>(
name=<js>"petId"</js>,
description=<js>"Pet id to delete"</js>,
example=<js>"123"</js>
)
- <jk>long</jk> petId
+ <jk>long</jk> <jv>petId</jv>
) <jk>throws</jk> IdNotFound, NotAcceptable;
...
@@ -88,8 +88,8 @@ Dual-purpose (end-to-end) interfaces
summary=<js>"Deletes a pet"</js>,
...
)
- <jk>public</jk> Ok deletePet(String apiKey, long petId) <jk>throws</jk> IdNotFound, NotAcceptable {
- <jsf>store</jsf>.removePet(petId);
+ <jk>public</jk> Ok deletePet(String <jv>apiKey</jv>, <jk>long</jk> <jv>petId</jv>) <jk>throws</jk> IdNotFound, NotAcceptable {
+ <jsf>store</jsf>.removePet(<jv>petId</jv>);
<jk>return</jk> <jsf>OK</jsf>;
}
</p>
@@ -97,13 +97,12 @@ Dual-purpose (end-to-end) interfaces
Then use the interface as a remote resource like so:
</p>
<p class='bpcode w800'>
- <jk>try</jk> (RestClient rc = RestClient.<jsm>create</jsm>().json().rootUrl(<js>"http://localhost:10000"</js>).build()) {
- PetStore ps = rc.getRemote(PetStore.<jk>class</jk>);
+ RestClient client = RestClient.<jsm>create</jsm>().json().rootUrl(<js>"http://localhost:10000"</js>).build();
+ PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>);
- <jk>for</jk> (Pet x : ps.getPets()) {
- ps.deletePet(<js>"my-special-key"</js>, x.getId());
- System.<jsf>err</jsf>.println(<js>"Deleted pet: id="</js> + x.getId());
- }
+ <jk>for</jk> (Pet <jv>x</jv> : <jv>store</jv>.getPets()) {
+ <jv>store</jv>.deletePet(<js>"my-special-key"</js>, <jv>x</jv>.getId());
+ System.<jsf>err</jsf>.println(<js>"Deleted pet: id="</js> + <jv>x</jv>.getId());
}
</p>
<p>
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/12.LoggingAndDebugging.html b/juneau-doc/docs/Topics/09.juneau-rest-client/12.LoggingAndDebugging.html
index ae6cfa2..ac81d49 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/12.LoggingAndDebugging.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/12.LoggingAndDebugging.html
@@ -35,13 +35,16 @@ Logging and Debugging
<h5 class='figure'>Examples:</h5>
<p class='bpcode w800'>
- MyBean <jv>bean</jv> = RestClient
+ <jc>// A simple bean we're going to round-trip.</jc>
+ MyBean <jv>bean</jv> = <jk>new</jk> MyBean();
+
+ <jv>bean</jv> = RestClient
.<jsm>create</jsm>()
.simpleJson()
- .logRequests(DetailLevel.<jsf>FULL</jsf>, Level.<jsf>SEVERE</jsf>, (req,res)->req.getUri().endsWith(<js>"/bean"</js>))
+ .logRequests(DetailLevel.<jsf>FULL</jsf>, Level.<jsf>SEVERE</jsf>, (<jv>req</jv>,<jv>res</jv>)-><jv>req</jv>.getUri().endsWith(<js>"/bean"</js>))
.logToConsole()
.build()
- .post(<js>"http://localhost/bean"</js>, <jv>anotherBean</jv>)
+ .post(<js>"http://localhost/bean"</js>, <jv>bean</jv>)
.run()
.getBody().as(MyBean.<jk>class</jk>);
</p>
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/13.CustomizingHttpClient.html b/juneau-doc/docs/Topics/09.juneau-rest-client/13.CustomizingHttpClient.html
index fe8ca73..4afbafb 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/13.CustomizingHttpClient.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/13.CustomizingHttpClient.html
@@ -46,5 +46,5 @@ Customizing HttpClient
</p>
<p>
- Refer to the {@link org.apache.http.client.impl.HttpClientBuilder HTTP Client Builder API} for more information.
+ Refer to the {@link org.apache.http.client.impl.HttpClientBuilder HttpClientBuilder} docs for more information.
</p>
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/15.Authentication/01.BASIC.html b/juneau-doc/docs/Topics/09.juneau-rest-client/15.Authentication/01.BASIC.html
index 9da2c80..0a64d1b 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/15.Authentication/01.BASIC.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/15.Authentication/01.BASIC.html
@@ -23,7 +23,7 @@ BASIC Authentication
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Create a client that performs BASIC authentication using the specified user/pw.</jc>
- RestClient client = RestClient.<jsm>create</jsm>()
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>()
.basicAuth(<jsf>HOST</jsf>, <jsf>PORT</jsf>, <jsf>USER</jsf>, <jsf>PW</jsf>)
.build();
</p>
@@ -31,10 +31,10 @@ BASIC Authentication
This is functionally equivalent to the following:
</p>
<p class='bpcode w800'>
- RestClientBuilder builder = RestClient.<jsm>create</jsm>();
- AuthScope scope = <jk>new</jk> AuthScope(<jsf>HOST</jsf>, <jsf>PORT</jsf>);
- Credentials up = <jk>new</jk> UsernamePasswordCredentials(<jsf>USER</jsf>, <jsf>PW</jsf>);
- CredentialsProvider p = <jk>new</jk> BasicCredentialsProvider();
- p.setCredentials(scope, up);
- builder.setDefaultCredentialsProvider(p);
+ RestClientBuilder <jv>builder</jv> = RestClient.<jsm>create</jsm>();
+ AuthScope <jv>scope</jv> = <jk>new</jk> AuthScope(<jsf>HOST</jsf>, <jsf>PORT</jsf>);
+ Credentials <jv>up</jv> = <jk>new</jk> UsernamePasswordCredentials(<jsf>USER</jsf>, <jsf>PW</jsf>);
+ CredentialsProvider <jv>p</jv> = <jk>new</jk> BasicCredentialsProvider();
+ <jv>p</jv>.setCredentials(<jv>scope</jv>, <jv>up</jv>);
+ <jv>builder</jv>.setDefaultCredentialsProvider(<jv>p</jv>);
</p>
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/15.Authentication/02.FORM.html b/juneau-doc/docs/Topics/09.juneau-rest-client/15.Authentication/02.FORM.html
index 0f2614d..9cdaffd 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/15.Authentication/02.FORM.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/15.Authentication/02.FORM.html
@@ -24,14 +24,14 @@ FORM-based Authentication
authenticated client.
</p>
<p>
- The following example shows how the <c>JazzRestClient</c> class provides FORM-based
- authentication support.
+ The following example shows an implementation of a client that performs FORM-based authentication against
+ the IBM Jazz platform.
</p>
<p class='bpcode w800'>
<jd>/**
* Constructor.
*/</jd>
- <jk>public</jk> JazzRestClientBuilder(URI jazzUri, String user, String pw) <jk>throws</jk> IOException {
+ <jk>public</jk> JazzRestClientBuilder(URI <jv>jazzUri</jv>, String <jv>user</jv>, String <jv>pw</jv>) <jk>throws</jk> IOException {
...
}
@@ -40,46 +40,47 @@ FORM-based Authentication
*/</jd>
<ja>@Override</ja> <jc>/* RestClientBuilder */</jc>
<jk>protected</jk> CloseableHttpClient createHttpClient() <jk>throws</jk> Exception {
- CloseableHttpClient client = <jk>super</jk>.createHttpClient();
- formBasedAuthenticate(client);
- visitAuthenticatedURL(client);
- <jk>return</jk> client;
+ CloseableHttpClient <jv>client</jv> = <jk>super</jk>.createHttpClient();
+ formBasedAuthenticate(<jv>client</jv>);
+ visitAuthenticatedURL(<jv>client</jv>);
+ <jk>return</jk> <jv>client</jv>;
}
<jc>/*
* Performs form-based authentication against the Jazz server.
*/</jc>
- <jk>private void</jk> formBasedAuthenticate(HttpClient client) <jk>throws</jk> IOException {
+ <jk>private void</jk> formBasedAuthenticate(HttpClient <jv>client</jv>) <jk>throws</jk> IOException {
- URI uri2 = <jf>jazzUri</jf>.resolve(<js>"j_security_check"</js>);
- HttpPost request = <jk>new</jk> HttpPost(uri2);
- request.setConfig(RequestConfig.<jsm>custom</jsm>().setRedirectsEnabled(<jk>false</jk>).build());
+ URI <jv>uri2</jv> = <jf>jazzUri</jf>.resolve(<js>"j_security_check"</js>);
+ HttpPost <jv>request</jv> = <jk>new</jk> HttpPost(uri2);
+ <jv>request</jv>.setConfig(RequestConfig.<jsm>custom</jsm>().setRedirectsEnabled(<jk>false</jk>).build());
<jc>// Charset must explicitly be set to UTF-8 to handle user/pw with non-ascii characters.</jc>
- request.addHeader(<js>"Content-Type"</js>, <js>"application/x-www-form-urlencoded; charset=utf-8"</js>);
+ <jv>request</jv>.addHeader(<js>"Content-Type"</js>, <js>"application/x-www-form-urlencoded; charset=utf-8"</js>);
- NameValuePairs params = <jk>new</jk> NameValuePairs()
- .append(<jk>new</jk> BasicNameValuePair(<js>"j_username""</js>, <jf>user</jf>))
- .append(<jk>new</jk> BasicNameValuePair(<js>"j_password"</js>, <jf>pw</jf>));
- request.setEntity(<jk>new</jk> UrlEncodedFormEntity(params));
+ List<NameValuePair> <jv>params</jv> = AList.<jsm>of</jsm>(
+ BasicNameValuePair.<jsm>of</jsm>(<js>"j_username""</js>, <jf>user</jf>),
+ BasicNameValuePair.<jsm>of</jsm>(<js>"j_password"</js>, <jf>pw</jf>)
+ );
+ <jv>request</jv>.setEntity(<jk>new</jk> UrlEncodedFormEntity(<jv>params</jv>));
- HttpResponse response = client.execute(request);
+ HttpResponse <jv>response</jv> = <jv>client</jv>.execute(<jv>request</jv>);
<jk>try</jk> {
- <jk>int</jk> rc = response.getStatusLine().getStatusCode();
+ <jk>int</jk> <jv>rc</jv> = <jv>response</jv>.getStatusLine().getStatusCode();
- Header authMsg = response.getFirstHeader(<js>"X-com-ibm-team-repository-web-auth-msg"</js>);
- <jk>if</jk> (authMsg != <jk>null</jk>)
- <jk>throw new</jk> IOException(authMsg.getValue());
+ Header <jv>authMsg</jv> = <jv>response</jv>.getFirstHeader(<js>"X-com-ibm-team-repository-web-auth-msg"</js>);
+ <jk>if</jk> (<jv>authMsg</jv> != <jk>null</jk>)
+ <jk>throw new</jk> IOException(<jv>authMsg</jv>.getValue());
<jc>// The form auth request should always respond with a 200 ok or 302 redirect code</jc>
- <jk>if</jk> (rc == <jsf>SC_MOVED_TEMPORARILY</jsf>) {
- <jk>if</jk> (response.getFirstHeader(<js>"Location"</js>).getValue().matches(<js>"^.*/auth/authfailed.*$"</js>))
+ <jk>if</jk> (<jv>rc</jv> == <jsf>SC_MOVED_TEMPORARILY</jsf>) {
+ <jk>if</jk> (<jv>response</jv>.getFirstHeader(<js>"Location"</js>).getValue().matches(<js>"^.*/auth/authfailed.*$"</js>))
<jk>throw new</jk> IOException(<js>"Invalid credentials."</js>);
- } <jk>else if</jk> (rc != <jsf>SC_OK</jsf>) {
- <jk>throw new</jk> IOException(<js>"Unexpected HTTP status: "</js> + rc);
+ } <jk>else if</jk> (<jv>rc</jv> != <jsf>SC_OK</jsf>) {
+ <jk>throw new</jk> IOException(<js>"Unexpected HTTP status: "</js> + <jv>rc</jv>);
}
} <jk>finally</jk> {
- EntityUtils.<jsm>consume</jsm>(response.getEntity());
+ EntityUtils.<jsm>consume</jsm>(<jv>response</jv>.getEntity());
}
}
@@ -88,13 +89,13 @@ FORM-based Authentication
* authenticated URL has been visited. This same URL must also be visited after authenticating with j_security_check
* otherwise tomcat will not consider the session authenticated
*/</jc>
- <jk>private int</jk> visitAuthenticatedURL(HttpClient httpClient) <jk>throws</jk> IOException {
- HttpGet authenticatedURL = <jk>new</jk> HttpGet(<jf>jazzUri</jf>.resolve(<js>"authenticated/identity"</js>));
- HttpResponse response = httpClient.execute(authenticatedURL);
+ <jk>private int</jk> visitAuthenticatedURL(HttpClient <jv>httpClient</jv>) <jk>throws</jk> IOException {
+ HttpGet <jv>authenticatedURL</jv> = <jk>new</jk> HttpGet(<jf>jazzUri</jf>.resolve(<js>"authenticated/identity"</js>));
+ HttpResponse <jv>response</jv> = <jv>httpClient</jv>.execute(<jv>authenticatedURL</jv>);
<jk>try</jk> {
- <jk>return</jk> response.getStatusLine().getStatusCode();
+ <jk>return</jk> <jv>response</jv>.getStatusLine().getStatusCode();
} <jk>finally</jk> {
- EntityUtils.<jsm>consume</jsm>(response.getEntity());
+ EntityUtils.<jsm>consume</jsm>(<jv>response</jv>.getEntity());
}
}
</p>
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/15.Authentication/03.OIDC.html b/juneau-doc/docs/Topics/09.juneau-rest-client/15.Authentication/03.OIDC.html
index ec1e021..118506b 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/15.Authentication/03.OIDC.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/15.Authentication/03.OIDC.html
@@ -16,14 +16,14 @@
OIDC Authentication
<p>
- The following example shows how the <c>JazzRestClient</c> class provides OIDC authentication
- support.
+ The following example shows an implementation of a client that performs OIDC authentication against
+ the IBM Jazz platform.
</p>
<p class='bpcode w800'>
<jd>/**
* Constructor.
*/</jd>
- <jk>public</jk> JazzRestClientBuilder(URI jazzUri, String user, String pw) <jk>throws</jk> IOException {
+ <jk>public</jk> JazzRestClientBuilder(URI <jv>jazzUri</jv>, String <jv>user</jv>, String <jv>pw</jv>) <jk>throws</jk> IOException {
...
}
@@ -32,108 +32,108 @@ OIDC Authentication
*/</jd>
<ja>@Override</ja> <jc>/* RestClientBuilder */</jc>
<jk>protected</jk> CloseableHttpClient createHttpClient() <jk>throws</jk> Exception {
- CloseableHttpClient client = <jk>super</jk>.createHttpClient();
- oidcAuthenticate(client);
- <jk>return</jk> client;
- }
+ CloseableHttpClient <jv>client</jv> = <jk>super</jk>.createHttpClient();
+ oidcAuthenticate(<jv>client</jv>);
+ <jk>return</jk> <jv>client</jv>;
+ }
- <jk>private void</jk> oidcAuthenticate(HttpClient client) <jk>throws</jk> IOException {
+ <jk>private void</jk> oidcAuthenticate(HttpClient <jv>client</jv>) <jk>throws</jk> IOException {
- HttpGet request = <jk>new</jk> HttpGet(<jf>jazzUri</jf>);
- request.setConfig(RequestConfig.<jsm>custom</jsm>().setRedirectsEnabled(<jk>false</jk>).build());
+ HttpGet <jv>request</jv> = <jk>new</jk> HttpGet(<jf>jazzUri</jf>);
+ <jv>request</jv>.setConfig(RequestConfig.<jsm>custom</jsm>().setRedirectsEnabled(<jk>false</jk>).build());
<jc>// Charset must explicitly be set to UTF-8 to handle user/pw with non-ascii characters.</jc>
- request.addHeader(<js>"Content-Type"</js>, <js>"application/x-www-form-urlencoded; charset=utf-8"</js>);
+ <jv>request</jv>.addHeader(<js>"Content-Type"</js>, <js>"application/x-www-form-urlencoded; charset=utf-8"</js>);
- HttpResponse response = client.execute(request);
+ HttpResponse <jv>response</jv> = <jv>client</jv>.execute(<jv>request</jv>);
<jk>try</jk> {
- <jk>int</jk> code = response.getStatusLine().getStatusCode();
+ <jk>int</jk> <jv>code</jv> = <jv>response</jv>.getStatusLine().getStatusCode();
<jc>// Already authenticated</jc>
- <jk>if</jk> (code == <jsf>SC_OK</jsf>)
+ <jk>if</jk> (<jv>code</jv> == <jsf>SC_OK</jsf>)
<jk>return</jk>;
- <jk>if</jk> (code != <jsf>SC_UNAUTHORIZED</jsf>)
+ <jk>if</jk> (<jv>code</jv> != <jsf>SC_UNAUTHORIZED</jsf>)
<jk>throw new</jk> RestCallException(<js>"Unexpected response during OIDC authentication: "</js>
- + response.getStatusLine());
+ + <jv>response</jv>.getStatusLine());
<jc>// x-jsa-authorization-redirect</jc>
- String redirectUri = getHeader(response, <js>"X-JSA-AUTHORIZATION-REDIRECT"</js>);
+ String <jv>redirectUri</jv> = getHeader(<jv>response</jv>, <js>"X-JSA-AUTHORIZATION-REDIRECT"</js>);
- <jk>if</jk> (redirectUri == <jk>null</jk>)
+ <jk>if</jk> (<jv>redirectUri</jv> == <jk>null</jk>)
<jk>throw new</jk> RestCallException(<js>"Expected a redirect URI during OIDC authentication: "</js>
- + response.getStatusLine());
+ + <jv>response</jv>.getStatusLine());
<jc>// Handle Bearer Challenge</jc>
- HttpGet method = <jk>new</jk> HttpGet(redirectUri + <js>"&prompt=none"</js>);
- addDefaultOidcHeaders(method);
+ HttpGet <jv>method</jv> = <jk>new</jk> HttpGet(<jv>redirectUri</jv> + <js>"&prompt=none"</js>);
+ addDefaultOidcHeaders(<jv>method</jv>);
- response = client.execute(method);
+ <jv>response</jv> = <jv>client</jv>.execute(<jv>method</jv>);
- code = response.getStatusLine().getStatusCode();
+ <jv>code</jv> = <jv>response</jv>.getStatusLine().getStatusCode();
- <jk>if</jk> (code != <jsf>SC_OK</jsf>)
+ <jk>if</jk> (<jv>code</jv> != <jsf>SC_OK</jsf>)
<jk>throw new</jk> RestCallException(<js>"Unexpected response during OIDC authentication phase 2: "</js>
- + response.getStatusLine());
+ + <jv>response</jv>.getStatusLine());
- String loginRequired = getHeader(response, <js>"X-JSA-LOGIN-REQUIRED"</js>);
+ String <jv>loginRequired</jv> = getHeader(<jv>response</jv>, <js>"X-JSA-LOGIN-REQUIRED"</js>);
- <jk>if</jk> (! <js>"true"</js>.equals(loginRequired))
+ <jk>if</jk> (! <js>"true"</js>.equals(<jv>loginRequired</jv>))
<jk>throw new</jk> RestCallException(<js>"X-JSA-LOGIN-REQUIRED header not found on response during OIDC authentication phase 2: "</js>
- + response.getStatusLine());
+ + <jv>response</jv>.getStatusLine());
- method = <jk>new</jk> HttpGet(redirectUri + <js>"&prompt=none"</js>);
+ <jv>method</jv> = <jk>new</jk> HttpGet(<jv>redirectUri</jv> + <js>"&prompt=none"</js>);
- addDefaultOidcHeaders(method);
- response = client.execute(method);
+ addDefaultOidcHeaders(<jv>method</jv>);
+ <jv>response</jv> = <jv>client</jv>.execute(<jv>method</jv>);
- code = response.getStatusLine().getStatusCode();
+ <jv>code</jv> = <jv>response</jv>.getStatusLine().getStatusCode();
- <jk>if</jk> (code != <jsf>SC_OK</jsf>)
+ <jk>if</jk> (<jv>code</jv> != <jsf>SC_OK</jsf>)
<jk>throw new</jk> RestCallException(<js>"Unexpected response during OIDC authentication phase 3: "</js>
- + response.getStatusLine());
+ + <jv>response</jv>.getStatusLine());
<jc>// Handle JAS Challenge</jc>
- method = <jk>new</jk> HttpGet(redirectUri);
- addDefaultOidcHeaders(method);
+ <jv>method</jv> = <jk>new</jk> HttpGet(<jv>redirectUri</jv>);
+ addDefaultOidcHeaders(<jv>method</jv>);
- response = client.execute(method);
+ <jv>response</jv> = <jv>client</jv>.execute(<jv>method</jv>);
- code = response.getStatusLine().getStatusCode();
+ <jv>code</jv> = <jv>response</jv>.getStatusLine().getStatusCode();
- <jk>if</jk> (code != <jsf>SC_OK</jsf>)
+ <jk>if</jk> (<jv>code</jv> != <jsf>SC_OK</jsf>)
<jk>throw new</jk> RestCallException(<js>"Unexpected response during OIDC authentication phase 4: "</js>
- + response.getStatusLine());
+ + <jv>response</jv>.getStatusLine());
- <jf>cookie</jf> = getHeader(response, <js>"Set-Cookie"</js>);
+ <jf>cookie</jf> = getHeader(<jv>response</jv>, <js>"Set-Cookie"</js>);
- Header[] defaultHeaders = <jk>new</jk> Header[] {
- <jk>new</jk> BasicHeader(<js>"User-Agent"</js>, <js>"Jazz Native Client"</js>),
- <jk>new</jk> BasicHeader(<js>"X-com-ibm-team-configuration-versions"</js>,
+ Header[] <jv>defaultHeaders</jv> = <jk>new</jk> Header[] {
+ BasicStringHeader.<jsm>of</jsm>(<js>"User-Agent"</js>, <js>"Jazz Native Client"</js>),
+ BasicStringHeader.<jsm>of</jsm>(<js>"X-com-ibm-team-configuration-versions"</js>,
<js>"com.ibm.team.rtc=6.0.0,com.ibm.team.jazz.foundation=6.0"</js>),
- <jk>new</jk> BasicHeader(<js>"Accept"</js>, <js>"text/json"</js>),
- <jk>new</jk> BasicHeader(<js>"Authorization"</js>, <js>"Basic "</js>
+ BasicStringHeader.<jsm>of</jsm>(<js>"Accept"</js>, <js>"text/json"</js>),
+ BasicStringHeader.<jsm>of</jsm>(<js>"Authorization"</js>, <js>"Basic "</js>
+ StringUtils.<jsm>base64EncodeToString</jsm>(<jf>user</jf> + <js>":"</js> + <jf>pw</jf>)),
- <jk>new</jk> BasicHeader(<js>"Cookie"</js>, cookie)
+ BasicStringHeader.<jsm>of</jsm>(<js>"Cookie"</js>, <jf>cookie</jf>)
};
- setDefaultHeaders(Arrays.<jsm>asList</jsm>(defaultHeaders));
+ setDefaultHeaders(AList.<jsm>of</jsm>(<jv>defaultHeaders</jv>));
} <jk>finally</jk> {
- EntityUtils.<jsm>consume</jsm>(response.getEntity());
+ EntityUtils.<jsm>consume</jsm>(<jv>response</jv>.getEntity());
}
}
- <jk>private void</jk> addDefaultOidcHeaders(HttpRequestBase method) {
- method.addHeader(<js>"User-Agent"</js>, <js>"Jazz Native Client"</js>);
- method.addHeader(<js>"X-com-ibm-team-configuration-versions"</js>,
+ <jk>private void</jk> addDefaultOidcHeaders(HttpRequestBase <jv>method</jv>) {
+ <jv>method</jv>.addHeader(<js>"User-Agent"</js>, <js>"Jazz Native Client"</js>);
+ <jv>method</jv>.addHeader(<js>"X-com-ibm-team-configuration-versions"</js>,
<js>"com.ibm.team.rtc=6.0.0,com.ibm.team.jazz.foundation=6.0"</js>);
- method.addHeader(<js>"Accept"</js>, <js>"text/json"</js>);
+ <jv>method</jv>.addHeader(<js>"Accept"</js>, <js>"text/json"</js>);
<jk>if</jk> (<jf>cookie</jf> != <jk>null</jk>) {
- method.addHeader(<js>"Authorization"</js>, <js>"Basic "</js>
+ <jv>method</jv>.addHeader(<js>"Authorization"</js>, <js>"Basic "</js>
+ StringUtils.<jsm>base64EncodeToString</jsm>(<jf>user</jf> + <js>":"</js> + <jf>pw</jf>));
- method.addHeader(<js>"Cookie"</js>, cookie);
+ <jv>method</jv>.addHeader(<js>"Cookie"</js>, <jf>cookie</jf>);
}
}
</p>
diff --git a/juneau-doc/src/main/javadoc/overview.html b/juneau-doc/src/main/javadoc/overview.html
index 905f17e..635639c 100644
--- a/juneau-doc/src/main/javadoc/overview.html
+++ b/juneau-doc/src/main/javadoc/overview.html
@@ -470,9 +470,9 @@
<li><p><a class='doclink' href='#juneau-rest-client.ResponseBody'>Response Body</a><span class='update'><b>8.1.4-new</b></span></p>
<li><p><a class='doclink' href='#juneau-rest-client.CustomCallHandlers'>Custom Call Handlers</a><span class='update'><b>8.1.4-new</b></span></p>
<li><p><a class='doclink' href='#juneau-rest-client.Interceptors'>Interceptors</a><span class='update'><b>8.1.4-new</b></span></p>
- <li><p><a class='doclink' href='#juneau-rest-client.RestProxies'>REST Proxies</a><span class='update'><b>8.1.4-new</b></span></p>
+ <li><p><a class='doclink' href='#juneau-rest-client.RestProxies'>REST Proxies</a><span class='update'><b>8.1.4-updated</b></span></p>
<ol>
- <li><p><a class='doclink' href='#juneau-rest-client.RestProxies.Remote'>@Remote</a><span class='update'>8.1.2-updated</span></p>
+ <li><p><a class='doclink' href='#juneau-rest-client.RestProxies.Remote'>@Remote</a><span class='update'>8.1.2-updated,<b>8.1.4-updated</b></span></p>
<li><p><a class='doclink' href='#juneau-rest-client.RestProxies.RemoteMethod'>@RemoteMethod</a><span class='update'><b>8.1.4-updated</b></span></p>
<li><p><a class='doclink' href='#juneau-rest-client.RestProxies.Body'>@Body</a></p>
<li><p><a class='doclink' href='#juneau-rest-client.RestProxies.FormData'>@FormData</a></p>
@@ -22579,7 +22579,7 @@
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Create a basic REST client with JSON support and download a bean.</jc>
- MyBean bean = RestClient.<jsm>create</jsm>()
+ MyBean <jv>bean</jv> = RestClient.<jsm>create</jsm>()
.simpleJson()
.build()
.get(<jsf>URI</jsf>)
@@ -22594,17 +22594,17 @@
</p>
<p class='bpcode w800'>
- RestClientBuilder builder = RestClient.<jsm>create</jsm>().simpleJson();
- RestClient client = builder.build();
- RestRequest req = client.get(<jsf>URI</jsf>);
- RestResponse res = req.run();
- RestResponseStatusLineAssertion statusLineAssertion = res.assertStatus();
- FluentIntegerAssertion<RestResponse> codeAssertion = statusLineAssertion.code();
- res = codeAssertion.is(200);
- FluentStringAssertion<RestResponse> headerAssertion = res.assertHeader(<js>"Content-Type"</js>);
- res = headerAssertion.matchesSimple(<js>"application/json*"</js>);
- RestResponseBody body = res.getBody();
- MyBean bean = body.as(MyBean.<jk>class</jk>);
+ RestClientBuilder <jv>builder</jv> = RestClient.<jsm>create</jsm>().simpleJson();
+ RestClient <jv>client</jv> = <jv>builder</jv>.build();
+ RestRequest <jv>req</jv> = <jv>client</jv>.get(<jsf>URI</jsf>);
+ RestResponse <jv>res</jv> = <jv>req</jv>.run();
+ RestResponseStatusLineAssertion <jv>statusLineAssertion</jv> = <jv>res</jv>.assertStatus();
+ FluentIntegerAssertion<RestResponse> <jv>codeAssertion</jv> = <jv>statusLineAssertion</jv>.code();
+ <jv>res</jv> = <jv>codeAssertion</jv>.is(200);
+ FluentStringAssertion<RestResponse> <jv>headerAssertion</jv> = <jv>res</jv>.assertHeader(<js>"Content-Type"</js>);
+ <jv>res</jv> = <jv>headerAssertion</jv>.matchesSimple(<js>"application/json*"</js>);
+ RestResponseBody <jv>body</jv> = <jv>res</jv>.getBody();
+ MyBean <jv>bean</jv> = <jv>body</jv>.as(MyBean.<jk>class</jk>);
</p>
<p>
@@ -22619,17 +22619,18 @@
<ja>@RemoteMethod</ja>(httpMethod=<jsf>POST</jsf>, path=<js>"/pets"</js>)
Pet addPet(
- <ja>@Body</ja> CreatePet pet,
- <ja>@Header</ja>(<js>"E-Tag"</js>) UUID etag,
- <ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> debug
+ <ja>@Body</ja> CreatePet <jv>pet</jv>,
+ <ja>@Header</ja>(<js>"E-Tag"</js>) UUID <jv>etag</jv>,
+ <ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> <jv>debug</jv>
);
}
<jc>// Use a RestClient with default Simple JSON support.</jc>
- RestClient client = RestClient.<jsm>create</jsm>().simpleJson().build();
- PetStore store = client.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
- CreatePet cp = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
- Pet p = store.addPet(cp, UUID.<jsm>randomUUID</jsm>(), <jk>true</jk>);
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().simpleJson().build();
+
+ PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
+ CreatePet <jv>createPet</jv> = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
+ Pet <jv>pet</jv> = <jv>store</jv>.addPet(<jv>createPet</jv>, UUID.<jsm>randomUUID</jsm>(), <jk>true</jk>);
</p>
<p>
@@ -22655,10 +22656,10 @@
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Create a client where all URIs are relative to localhost.</jc>
- RestClient client = RestClient.<jsm>create</jsm>().json().rootUri(<js>"http://localhost:10000"</js>).build();
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json().rootUri(<js>"http://localhost:10000"</js>).build();
<jc>// Use relative paths.</jc>
- String body = client.get(<js>"/subpath"</js>).run().getBody().asString();
+ String <jv>body</jv> = <jv>client</jv>.get(<js>"/subpath"</js>).run().getBody().asString();
</p>
<p>
@@ -22706,10 +22707,10 @@
<p class='bpcode w800'>
<jc>// Consuming the response, so use run().</jc>
- String body = client.get(<jsf>URI</jsf>).run().getBody().asString();
+ String <jv>body</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).run().getBody().asString();
<jc>// Only interested in response status code, so use complete().</jc>
- <jk>int</jk> status = client.get(<jsf>URI</jsf>).complete().getStatusCode();
+ <jk>int</jk> <jv>status</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).complete().getStatusCode();
</p>
<!-- ==================================================================================================== -->
@@ -22739,7 +22740,7 @@
<p class='bpcode w800'>
<jc>// Create a basic REST client with Simplified-JSON support.</jc>
<jc>// Typically easier to use when performing unit tests.</jc>
- RestClient c = RestClient.<jsm>create</jsm>().simpleJson().build();
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().simpleJson().build();
</p>
<p>
@@ -22748,21 +22749,21 @@
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Create a REST client with support for multiple languages.</jc>
- RestClient c = RestClient.<jsm>create</jsm>().json().xml().openApi().build();
+ RestClient <jv>client1</jv> = RestClient.<jsm>create</jsm>().json().xml().openApi().build();
<jc>// Create a REST client with support for all supported languages.</jc>
- RestClient c = RestClient.<jsm>create</jsm>().universal().build();
+ RestClient <jv>client2</jv> = RestClient.<jsm>create</jsm>().universal().build();
</p>
<p>
- When using clients with multiple language support, you must specify the <c>Content-Type</c> header on requests
- with bodies to specify which serializer should be selected.
+ When using clients with multiple language support, the request language is selected by setting the <c>Content-Type</c>
+ request header.
</p>
<p class='bpcode w800'>
<jc>// Create a REST client with support for multiple languages.</jc>
- RestClient c = RestClient.<jsm>create</jsm>().universal().build();
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().universal().build();
- c.post(<jsf>URI</jsf>, myBean).contentType(<js>"application/json"</js>).complete().assertStatus().is(200);
+ <jv>client</jv>.post(<jsf>URI</jsf>, myBean).contentType(<js>"application/json"</js>).complete().assertStatus().is(200);
</p>
<p>
@@ -22770,10 +22771,10 @@
</p>
<p class='bpcode w800'>
<jc>// Create a REST client with no default languages supported.</jc>
- RestClient c = RestClient.<jsm>create</jsm>().build();
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().build();
<jc>// Use JSON for this request.</jc>
- c.post(<jsf>URI</jsf>, myBean).json().complete().assertStatus().is(200);
+ <jv>client</jv>.post(<jsf>URI</jsf>, myBean).json().complete().assertStatus().is(200);
</p>
<p>
@@ -22784,10 +22785,10 @@
<p class='bpcode w800'>
<jc>// Create a basic REST client with JSON support.</jc>
<jc>// Use single-quotes and whitespace.</jc>
- RestClient c = RestClient.<jsm>create</jsm>().json().sq().ws().build();
+ RestClient <jv>client1</jv> = RestClient.<jsm>create</jsm>().json().sq().ws().build();
<jc>// Same, but using properties.</jc>
- RestClient c = RestClient
+ RestClient <jv>client2</jv> = RestClient
.<jsm>create</jsm>()
.json()
.set(<jsf>WSERIALIZER_quoteChar</jsf>, <js>'\''</js>)
@@ -22852,6 +22853,38 @@
</ul>
</ul>
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client that adds a "Foo: bar" header to every request.</jc>
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().header(<js>"Foo"</js>, <js>"bar"</js>).build();
+
+ <jc>// Or do it on every request.</jc>
+ String <jv>response</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).header(<js>"Foo"</js>, <js>"bar"</js>).run().getBody().asString();
+</p>
+
+<p>
+ {@link org.apache.juneau.rest.client2.RestClientBuilder#headers(Object...) headers(Object...)} allows you to pass in a variety
+ of header objects, and {@link org.apache.juneau.rest.client2.RestClientBuilder#headerPairs(Object...) headerPairs(Object...)} allows
+ you to specify several headers in a compact fashion.
+</p>
+
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client that adds a bunch of headers to every request.</jc>
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
+ .headers(
+ AMap.<jsm>of</jsm>(<js>"Foo"</js>,<js>"bar"</js>,<js>"Baz"</js>,<js>"qux"</js>) <jc>// Arbitrary key/value pairs.</jc>
+ BasicStringHeader.<jsm>of</jsm>(<js>"Foo"</js>,<js>"bar"</js>) <jc>// A Header object.</jc>
+ BasicStringHeader.<jsm>of</jsm>(<js>"Foo"</js>,()->getBar()) <jc>// A dynamic Header object.</jc>
+ Accept.<jsm>of</jsm>(<js>"application/json"</js>) <jc>// Predefined Header objects.</jc>
+ HeaderSupplier.<jsm>ofPairs</jsm>(<js>"Foo"</js>,<js>"bar"</js>) <jc>// A dynamically changing list of Header objects.</jc>
+ AList.<jsm>of</jsm>(ContentType.<jsm>of</jsm>(<js>"application/json"</js>)) <jc>// A list of anything else on this list.</jc>
+ )
+ .headerPairs(<js>"Foo"</js>,<js>"bar"</js>,<js>"Baz"</js>,<js>"qux"</js>)
+ .build();
+</p>
+
<p>
Additionally, methods are provided on the client builder and per request for all standard HTTP headers
such as {@link org.apache.juneau.rest.client2.RestClientBuilder#authorization(Object) authorization(Object)}.
@@ -22860,13 +22893,13 @@
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Create a client that adds an Authorization header to every request.</jc>
- RestClient client = RestClient.<jsm>create</jsm>().authorization(<js>"Foo"</js>).build();
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().authorization(<js>"Foo"</js>).build();
<jc>// Or do it per-request.</jc>
- String response = client.get(<jsf>URI</jsf>).authorization(<js>"Foo"</js>).run().getBody().asString();
+ String <jv>response</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).authorization(<js>"Foo"</js>).run().getBody().asString();
<jc>// Or use an HttpHeader.</jc>
- response = client.get(<jsf>URI</jsf>).headers(Authorization.<jsm>of</jsm>(<js>"Foo"</js>)).run().getBody().asString();
+ <jv>response</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).headers(Authorization.<jsm>of</jsm>(<js>"Foo"</js>)).run().getBody().asString();
</p>
<p>
@@ -22877,18 +22910,18 @@
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Create a client that adds a dynamic Authorization header to every request.</jc>
- RestClient c = RestClient.<jsm>create</jsm>().header(<js>"Authorization"</js>, ()->getMyAuthToken()).build();
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().header(<js>"Authorization"</js>, ()->getMyAuthToken()).build();
</p>
<p>
- The {@link org.apache.juneau.httppart.HttpPartSchema} API allows you to define OpenAPI schemas to POJO data structures on both requests
- and responses.
+ The {@link org.apache.juneau.httppart.HttpPartSchema} API allows you to define OpenAPI schemas to POJO data structures on request headers.
</p>
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Create a client that adds a header "Foo: bar|baz" to every request.</jc>
- RestClient c = RestClient.<jsm>create</jsm>()
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
.header(<js>"Foo"</js>, AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>), <jsf>T_ARRAY_PIPES</jsf>)
.build();
</p>
@@ -22901,6 +22934,9 @@
<li>Methods that pass in POJOs convert values to strings using the part serializers. Methods that pass in <c>Header</c> or
<c>NameValuePair</c> objects use the values returned by that bean directly.
</ul>
+<ul class='seealso'>
+ <li class='jp'>{@link org.apache.juneau.http.header} - Predefined {@link org.apache.http.Header} beans.
+</ul>
</div><!-- END: 9.2 - juneau-rest-client.RequestHeaders -->
<!-- ==================================================================================================== -->
@@ -22934,14 +22970,53 @@
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Create a client that adds a ?foo=bar query parameter to every request.</jc>
- RestClient client = RestClient.<jsm>create</jsm>().query(<js>"foo"</js>, <js>"bar"</js>).build();
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().query(<js>"foo"</js>, <js>"bar"</js>).build();
<jc>// Or do it on every request.</jc>
- String response = client.get(<jsf>URI</jsf>).query(<js>"foo"</js>, <js>"bar"</js>).run().getBody().asString();
+ String <jv>response</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).query(<js>"foo"</js>, <js>"bar"</js>).run().getBody().asString();
+</p>
+
+<p>
+ {@link org.apache.juneau.rest.client2.RestClientBuilder#queries(Object...) queries(Object...)} allows you to pass in a variety
+ of query parameter objects, and {@link org.apache.juneau.rest.client2.RestClientBuilder#queryPairs(Object...) queryPairs(Object...)} allows
+ you to specify several query parameters in a compact fashion.
+</p>
+
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client that adds a bunch of query parameters to every request.</jc>
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
+ .queries(
+ AMap.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>,<js>"baz"</js>,<js>"qux"</js>) <jc>// Arbitrary key/value pairs.</jc>
+ BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>) <jc>// A NameValuePair object.</jc>
+ BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>,()->getBar()) <jc>// A dynamic NameValuePair object.</jc>
+ NameValuePairSupplier.<jsm>ofPairs</jsm>(<js>"foo"</js>,<js>"bar"</js>) <jc>// A dynamically changing list of NameValuePair objects.</jc>
+ AList.<jsm>of</jsm>(BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>)) <jc>// A list of anything else on this list.</jc>
+ )
+ .queryPairs(<js>"foo"</js>,<js>"bar"</js>,<js>"baz"</js>,<js>"qux"</js>)
+ .build();
+</p>
+
+<p>
+ The {@link org.apache.juneau.httppart.HttpPartSchema} API allows you to define OpenAPI schemas to POJO data structures on query parameters.
+</p>
+
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client that adds a query parameter "foo=bar|baz" to every request.</jc>
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
+ .query(<js>"foo"</js>, AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>), <jsf>T_ARRAY_PIPES</jsf>)
+ .build();
+</p>
+
+<p>
+ The methods with {@link org.apache.juneau.AddFlag} parameters allow you to control whether new query parameters get appended, prepended, or
+ replace existing query parameters with the same name.
</p>
<ul class='notes'>
- <li>Like header values, dynamic values and OpenAPI schemas are supported.
<li>Methods that pass in POJOs convert values to strings using the part serializers. Methods that pass in <c>NameValuePair</c>
objects use the values returned by that bean directly.
</ul>
@@ -22975,6 +23050,55 @@
</ul>
</ul>
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client that adds a foo=bar form-data parameter to every request.</jc>
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().formData(<js>"foo"</js>, <js>"bar"</js>).build();
+
+ <jc>// Or do it on every request.</jc>
+ String <jv>response</jv> = <jv>client</jv>.formPost(<jsf>URI</jsf>).formData(<js>"foo"</js>, <js>"bar"</js>).run().getBody().asString();
+</p>
+
+<p>
+ {@link org.apache.juneau.rest.client2.RestClientBuilder#formDatas(Object...) formDatas(Object...)} allows you to pass in a variety
+ of form-data parameter objects, and {@link org.apache.juneau.rest.client2.RestClientBuilder#formDataPairs(Object...) formDataPairs(Object...)} allows
+ you to specify several form-data parameters in a compact fashion.
+</p>
+
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client that adds a bunch of form-data parameters to every request.</jc>
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
+ .formDatas(
+ AMap.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>,<js>"baz"</js>,<js>"qux"</js>) <jc>// Arbitrary key/value pairs.</jc>
+ BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>) <jc>// A NameValuePair object.</jc>
+ BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>,()->getBar()) <jc>// A dynamic NameValuePair object.</jc>
+ NameValuePairSupplier.<jsm>ofPairs</jsm>(<js>"foo"</js>,<js>"bar"</js>) <jc>// A dynamically changing list of NameValuePair objects.</jc>
+ AList.<jsm>of</jsm>(BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>)) <jc>// A list of anything else on this list.</jc>
+ )
+ .formDataPairs(<js>"foo"</js>,<js>"bar"</js>,<js>"baz"</js>,<js>"qux"</js>)
+ .build();
+</p>
+
+<p>
+ The {@link org.apache.juneau.httppart.HttpPartSchema} API allows you to define OpenAPI schemas to POJO data structures on form-data parameters.
+</p>
+
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client that adds a form-data parameter "foo=bar|baz" to every request.</jc>
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
+ .formData(<js>"foo"</js>, AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>), <jsf>T_ARRAY_PIPES</jsf>)
+ .build();
+</p>
+
+<p>
+ The methods with {@link org.apache.juneau.AddFlag} parameters allow you to control whether new form-data parameters get appended, prepended, or
+ replace existing form-data parameters with the same name.
+</p>
+
<ul class='notes'>
<li>Like header values, dynamic values and OpenAPI schemas are supported.
<li>Methods that pass in POJOs convert values to strings using the part serializers. Methods that pass in <c>NameValuePair</c>
@@ -23020,6 +23144,33 @@
{@link java.util.function.Supplier} - A supplier of anything on this list.
</ul>
+<h5 class='figure'>Examples:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client with Simple-JSON support.</jc>
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().simpleJson().build();
+
+ <jc>// Post a JSON-serialized bean.</jc>
+ <jv>client</jv>
+ .post(<jsf>URI</jsf>)
+ .body(<jv>bean</jv>)
+ .complete()
+ .assertStatus().code().is(200);
+
+ <jc>// Post contents from a reader.</jc>
+ <jv>client</jv>
+ .post(<jsf>URI</jsf>)
+ .body(<jk>new</jk> FileReader(<js>"/tmp/foo.json"</js>))
+ .complete()
+ .assertStatus().code().is(200);
+
+ <jc>// Post contents from an Apache HttpEntity object.</jc>
+ <jv>client</jv>
+ .post(<jsf>URI</jsf>)
+ .body(<jk>new</jk> StringEntity(<jv>jsonString</jv>, ContentType.<jsf>APPLICATION_JSON</jsf>))
+ .complete()
+ .assertStatus().code().is(200);
+</p>
+
<ul class='notes'>
<li>If the serializer on the client or request is explicitly set to <jk>null</jk>, POJOs will be converted to strings
using the registered part serializer as content type <js>"text/plain</js>. If the part serializer is also <jk>null</jk>,
@@ -23048,7 +23199,7 @@
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Only interested in status code.</jc>
- <jk>int</jk> statusCode = client.get(<jsf>URI</jsf>).complete().getStatusCode();
+ <jk>int</jk> <jv>statusCode</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).complete().getStatusCode();
</p>
<p>
@@ -23058,11 +23209,11 @@
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Interested in multiple values.</jc>
- Mutable<Integer> statusCode = Mutable.<jsm>create</jsm>();
- Mutable<String> reasonPhrase = Mutable.<jsm>create</jsm>();
+ Mutable<Integer> <jv>statusCode</jv> = Mutable.<jsm>create</jsm>();
+ Mutable<String> <jv>reasonPhrase</jv> = Mutable.<jsm>create</jsm>();
- client.get(<jsf>URI</jsf>).complete().getStatusCode(statusCode).getReasonPhrase(reasonPhrase);
- System.<jsf>err</jsf>.println(<js>"statusCode="</js>+statusCode.get()+<js>", reasonPhrase="</js>+reasonPhrase.get());
+ <jv>client</jv>.get(<jsf>URI</jsf>).complete().getStatusCode(<jv>statusCode</jv>).getReasonPhrase(<jv>reasonPhrase</jv>);
+ System.<jsf>err</jsf>.println(<js>"statusCode="</js>+<jv>statusCode</jv>.get()+<js>", reasonPhrase="</js>+<jv>reasonPhrase</jv>.get());
</p>
<ul class='notes'>
@@ -23078,15 +23229,15 @@
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Status assertion using a static value.</jc>
- String body = client.get(<jsf>URI</jsf>)
+ String <jv>body1</jv> = <jv>client</jv>.get(<jsf>URI</jsf>)
.run()
.assertStatus().code().isBetween(200,399)
.getBody().asString();
<jc>// Status assertion using a predicate.</jc>
- String body = client.get(<jsf>URI</jsf>)
+ String <jv>body2</jv> = <jv>client</jv>.get(<jsf>URI</jsf>)
.run()
- .assertStatus().code().passes(x -> x<400)
+ .assertStatus().code().passes(<jv>x</jv> -> <jv>x</jv><400)
.getBody().asString();
</p>
</div><!-- END: 9.6 - juneau-rest-client.ResponseStatus -->
@@ -23120,7 +23271,7 @@
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// See if response contains Location header.</jc>
- <jk>boolean</jk> hasLocationHeader = client.get(<jsf>URI</jsf>).complete().getHeader(<js>"Location"</js>).exists();
+ <jk>boolean</jk> <jv>hasLocationHeader</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).complete().getHeader(<js>"Location"</js>).exists();
</p>
<p>
@@ -23161,7 +23312,7 @@
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Parse the header "Foo: bar|baz".</jc>
- List<String> fooHeader = client
+ List<String> <jv>fooHeader</jv> = <jv>client</jv>
.get(<jsf>URI</jsf>)
.complete()
.getHeader(<js>"Foo"</js>).schema(<jsf>T_ARRAY_PIPES</jsf>).as(List.<jk>class</jk>, String.<jk>class</jk>);
@@ -23189,7 +23340,7 @@
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Assert the response content type is any sort of JSON.</jc>
- String body = client.get(<jsf>URI</jsf>)
+ String <jv>body</jv> = <jv>client</jv>.get(<jsf>URI</jsf>)
.run()
.getHeader(<js>"Content-Type"</js>).assertString().matchesSimple(<js>"application/json*"</js>)
.getBody().asString();
@@ -23238,36 +23389,40 @@
</ul>
</ul>
-<br>
-
<h5 class='figure'>Examples:</h5>
<p class='bpcode w800'>
+ <jc>// Parse into a bean.</jc>
+ MyBean <jv>bean</jv> = <jv>client</jv>
+ .get(<jsf>URI</jsf>)
+ .run()
+ .getBody().as(MyBean.<jk>class</jk>);
+
<jc>// Parse into a linked-list of strings.</jc>
- List<String> l = client
+ List<String> <jv>l1</jv> = <jv>client</jv>
.get(<jsf>URI</jsf>)
.run()
.getBody().as(LinkedList.<jk>class</jk>, String.<jk>class</jk>);
<jc>// Parse into a linked-list of beans.</jc>
- List<MyBean> l = client
+ List<MyBean> <jv>l2</jv> = <jv>client</jv>
.get(<jsf>URI</jsf>)
.run()
.getBody().as(LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>);
<jc>// Parse into a linked-list of linked-lists of strings.</jc>
- List<List<String>> l = client
+ List<List<String>> <jv>l3</jv> = <jv>client</jv>
.get(<jsf>URI</jsf>)
.run()
.getBody().as(LinkedList.<jk>class</jk>, LinkedList.<jk>class</jk>, String.<jk>class</jk>);
<jc>// Parse into a map of string keys/values.</jc>
- Map<String,String> m = client
+ Map<String,String> <jv>m4</jv> = <jv>client</jv>
.get(<jsf>URI</jsf>)
.run()
.getBody().as(TreeMap.<jk>class</jk>, String.<jk>class</jk>, String.<jk>class</jk>);
<jc>// Parse into a map containing string keys and values of lists containing beans.</jc>
- Map<String,List<MyBean>> m = client
+ Map<String,List<MyBean>> <jv>m5</jv> = <jv>client</jv>
.get(<jsf>URI</jsf>)
.run()
.getBody().as(TreeMap.<jk>class</jk>, String.<jk>class</jk>, List.<jk>class</jk>, MyBean.<jk>class</jk>);
@@ -23283,11 +23438,11 @@
<p class='bpcode w800'>
<jc>// Cache the response body so we can access it twice.</jc>
- InputStream inputStream = client
+ InputStream <jv>inputStream</jv> = <jv>client</jv>
.get(<jsf>URI</jsf>)
.run()
.cacheBody()
- .getBody().pipeTo(someOtherStream)
+ .getBody().pipeTo(<jv>someOtherStream</jv>)
.getBody().asInputStream();
</p>
@@ -23304,12 +23459,10 @@
</ul>
</ul>
-<br>
-
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Assert that the body contains the string "Success".</jc>
- String body = client
+ String <jv>body</jv> = <jv>client</jv>
.get(<jsf>URI</jsf>)
.run()
.getBody().assertString().contains(<js>"Success"</js>)
@@ -23324,7 +23477,7 @@
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Parse bean into POJO and then validate that it was parsed correctly.</jc>
- MyBean bean = client.get(<jsf>URI</jsf>)
+ MyBean <jv>bean</jv> = <jv>client</jv>.get(<jsf>URI</jsf>)
.run()
.getBody().assertObject(MyBean.<jk>class</jk>).json().is(<js>"{foo:'bar'}"</js>)
.getBody().as(MyBean.<jk>class</jk>);
@@ -23351,6 +23504,35 @@
</ul>
</ul>
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Our custom call handler.</jc>
+ <jk>public class</jk> MyRestCallHandler <jk>implements</jk> RestCallHandler {
+
+ <jk>private final</jk> RestClient <jf>client</jf>;
+
+ <jk>public</jk> MyRestCallHandler(RestClient <jv>client</jv>) {
+ <jk>this</jk>.<jf>client</jf> = <jv>client</jv>;
+ }
+
+ <ja>@Override</ja>
+ <jk>public</jk> HttpResponse run(HttpHost <jv>target</jv>, HttpRequest <jv>request</jv>, HttpContext <jv>context</jv>) <jk>throws</jk> IOException {
+ <jc>// Insert any special handling here.</jc>
+ <jc>// The following is the default behavior:</jc>
+ <jk>if</jk> (<jv>target</jv> == <jk>null</jk>)
+ <jk>return</jk> <jf>client</jf>.execute((HttpUriRequest)<jv>request</jv>, <jv>context</jv>);
+ <jk>return</jk> <jf>client</jf>.execute(<jv>target</jv>, <jv>request</jv>, <jv>context</jv>);
+ }
+ }
+
+ <jc>// Create a client that uses our custom handler.</jc>
+ RestClient <jv>client</jv> = RestClient()
+ .create()
+ .json()
+ .callHandler(MyCallHandler.<jk>class</jk>)
+ .build();
+</p>
+
<p>
Note that there are other ways of accomplishing this such as extending the {@link org.apache.juneau.rest.client2.RestClient} class and overriding
the {@link org.apache.juneau.rest.client2.RestClient#run(HttpHost,HttpRequest,HttpContext)} method
@@ -23383,36 +23565,43 @@
<li class='jm'>{@link org.apache.juneau.rest.client2.RestCallInterceptor#onClose(RestRequest,RestResponse) onClose(RestRequest,RestResponse)}
</ul>
</ul>
+
+<h5 class='section'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// Create a client with a customized interceptor.</jc>
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
+ .interceptors(
+ <jk>new</jk> RestCallInterceptor() {
+
+ <ja>@Override</ja>
+ <jk>public void</jk> onInit(RestRequest <jv>req</jv>) <jk>throws</jk> Exception {
+ <jc>// Intercept immediately after RestRequest object is created and all headers/query/form-data has been
+ // set on the request from the client.</jc>
+ }
+
+ <ja>@Override</ja>
+ <jk>public void</jk> onConnect(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> Exception {
+ <jc>// Intercept immediately after an HTTP response has been received.</jc>
+ }
+
+ <ja>@Override</ja>
+ <jk>public void</jk> onClose(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> Exception {
+ <jc>// Intercept when the response body is consumed.</jc>
+ }
+ }
+ )
+ .build();
+</p>
</div><!-- END: 9.10 - juneau-rest-client.Interceptors -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.RestProxies' id='juneau-rest-client.RestProxies'>9.11 - REST Proxies</a><span class='update'><b>8.1.4-new</b></span></h3>
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.RestProxies' id='juneau-rest-client.RestProxies'>9.11 - REST Proxies</a><span class='update'><b>8.1.4-updated</b></span></h3>
<div class='topic'><!-- START: 9.11 - juneau-rest-client.RestProxies -->
<p>
One of the more powerful features of the REST client class is the ability to produce Java interface proxies against
- arbitrary remote REST resources.
-</p>
-
-<h5 class='figure'>Example:</h5>
-<p class='bpcode w800'>
- <jc>// Define a Remote proxy for interacting with a REST interface.</jc>
- <ja>@Remote</ja>(path=<js>"/petstore"</js>)
- <jk>public interface</jk> PetStore {
- <ja>@RemoteMethod</ja>(httpMethod=<jsf>POST</jsf>, path=<js>"/pets"</js>)
- Pet addPet(
- <ja>@Body</ja> CreatePet pet,
- <ja>@Header</ja>(<js>"E-Tag"</js>) UUID etag,
- <ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> debug
- );
- }
-
- <jc>// Use a RestClient with default Simple JSON support.</jc>
- <jk>try</jk> (RestClient client = RestClient.<jsm>create</jsm>().simpleJson().build()) {
- PetStore store = client.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
- CreatePet cp = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
- Pet p = store.addPet(cp, UUID.<jsm>randomUUID</jsm>(), <jk>true</jk>);
- }
+ arbitrary 3rd party REST resources.
</p>
<p>
@@ -23425,47 +23614,10 @@
<li class='jm'><c>{@link org.apache.juneau.rest.client2.RestClient#getRemote(Class) getRemote(Class<T>)} <jk>returns</jk> T</c>
<li class='jm'><c>{@link org.apache.juneau.rest.client2.RestClient#getRemote(Class,Object) getRemote(Class<T>,Object)} <jk>returns</jk> T</c>
<li class='jm'><c>{@link org.apache.juneau.rest.client2.RestClient#getRemote(Class,Object,Serializer,Parser) getRemote(Class<T>,Object,Serializer,Parser)} <jk>returns</jk> T</c>
- <li class='jm'><c>{@link org.apache.juneau.rest.client2.RestClient#getRrpcInterface(Class) getRrpcInterface(Class<T>)} <jk>returns</jk> T</c>
- <li class='jm'><c>{@link org.apache.juneau.rest.client2.RestClient#getRrpcInterface(Class,Object) getRrpcInterface(Class<T>,Object)} <jk>returns</jk> T</c>
- <li class='jm'><c>{@link org.apache.juneau.rest.client2.RestClient#getRrpcInterface(Class,Object,Serializer,Parser) getRrpcInterface(Class<T>,Object,Serializer,Parser)} <jk>returns</jk> T</c>
</ul>
</ul>
<p>
- Two basic types of remote interfaces are provided:
-</p>
-
-<ul class='spaced-list'>
- <li>{@link org.apache.juneau.http.remote.Remote @Remote}-annotated interfaces. These can be defined against arbitrary external REST resources.
- <li>RPC-over-REST interfaces. These are Java interfaces that allow you to make method calls on server-side POJOs.
-</ul>
-
-
-
-
-
-
-
-
-
-
-<p>
- The <c>juneau-rest-client</c> library can also be used to define interface proxies against 3rd-party REST interfaces.
- This is an extremely powerful feature that allows you to quickly define easy-to-use interfaces against
- virtually any REST interface.
-</p>
-<p>
- Remote resources are instantiated using one of the following methods:
-</p>
-<ul class='javatree'>
- <li class='jc'>{@link org.apache.juneau.rest.client2.RestClient}
- <ul>
- <li class='jm'>{@link org.apache.juneau.rest.client2.RestClient#getRemote(Class) getRemote(Class)}
- <li class='jm'>{@link org.apache.juneau.rest.client2.RestClient#getRemote(Class,Object) getRemote(Class,Object)}
- <li class='jm'>{@link org.apache.juneau.rest.client2.RestClient#getRemote(Class,Object,Serializer,Parser) getRemote(Class,Object,Serializer,Parser)}
- </ul>
-</ul>
-<p>
Annotations are used on the interface and interface methods to specify how to convert input and output to HTTP headers, query parameters, form
post parameters, or request/response bodies.
</p>
@@ -23493,24 +23645,30 @@
<jk>public interface</jk> PetStore {
<ja>@RemoteMethod</ja>(method=<jsf>POST</jsf>, path=<js>"/pets"</js>)
- String addPet(
- <ja>@Body</ja> CreatePet pet,
- <ja>@Header</ja>(<js>"E-Tag"</js>) UUID etag,
- <ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> debug
+ Pet addPet(
+ <ja>@Body</ja> CreatePet <jv>createPet</jv>,
+ <ja>@Header</ja>(<js>"E-Tag"</js>) UUID <jv>etag</jv>,
+ <ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> <jv>debug</jv>
);
}
</p>
+
<p class='bpcode w800'>
<jc>// Use a RestClient with default Simple JSON support.</jc>
- <jk>try</jk> (RestClient client = RestClient.<jsm>create</jsm>().simpleJson().build()) {
- PetStore store = client.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
- CreatePet pet = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
- String response = store.createPet(pet, UUID.<jsm>randomUUID</jsm>(), <jk>true</jk>);
- }
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().simpleJson().build();
+
+ <jc>// Instantiate our proxy interface.</jc>
+ PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
+
+ <jc>// Use it to create a pet.</jc>
+ CreatePet <jv>createPet</jv> = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
+ Pet <jv>pet</jv> = <jv>store</jv>.addPet(<jv>createPet</jv>, UUID.<jsm>randomUUID</jsm>(), <jk>true</jk>);
</p>
+
<p>
The call above translates to the following REST call:
</p>
+
<p class='bpcode w800'>
POST http://localhost:10000/petstore/pets?debug=true HTTP/1.1
Accept: application/json
@@ -23540,18 +23698,24 @@
<!-- ==================================================================================================== -->
-<h4 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.RestProxies.Remote' id='juneau-rest-client.RestProxies.Remote'>9.11.1 - @Remote</a><span class='update'>8.1.2-updated</span></h4>
+<h4 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.RestProxies.Remote' id='juneau-rest-client.RestProxies.Remote'>9.11.1 - @Remote</a><span class='update'>8.1.2-updated,<b>8.1.4-updated</b></span></h4>
<div class='topic'><!-- START: 9.11.1 - juneau-rest-client.RestProxies.Remote -->
<p>
The {@link org.apache.juneau.http.remote.Remote @Remote} annotation is used on your interface class
to identify it as a REST proxy interface.
</p>
+
<ul class='javatree'>
<li class='ja'>{@link org.apache.juneau.http.remote.Remote}
<ul>
<li class='jf'>{@link org.apache.juneau.http.remote.Remote#path path}
+ <li class='jf'>{@link org.apache.juneau.http.remote.Remote#headers headers}
+ <li class='jf'>{@link org.apache.juneau.http.remote.Remote#headerSupplier headerSupplier}
+ <li class='jf'>{@link org.apache.juneau.http.remote.Remote#version version}
+ <li class='jf'>{@link org.apache.juneau.http.remote.Remote#versionHeader versionHeader}
</ul>
</ul>
+
<p>
The <ja>@Remote</ja> annotation is optional, but often included for code readability.
</p>
@@ -23561,41 +23725,139 @@
The {@link org.apache.juneau.http.remote.Remote#path @Remote(path)} annotation is used to define the
HTTP path of the REST service.
</p>
+
<p>
The path can be an absolute path to your REST service.
</p>
+
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<ja>@Remote</ja>(path=<js>"http://localhost:10000/petstore"</js>)
<jk>public interface</jk> PetStore {...}
</p>
<p class='bpcode w800'>
- PetStore p = client.getRemote(PetStore.<jk>class</jk>);
+ PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>);
</p>
+
+<p>
+ {@doc DefaultSvlVariables} can also be used in the path.
+</p>
+
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <jc>// URL is specified via a system property.</jc>
+ <ja>@Remote</ja>(path=<js>"$P{PetStoreUrl}"</js>)
+ <jk>public interface</jk> PetStore {...}
+</p>
+
<p>
When a relative path is specified, it's relative to the root-url defined on the <c>RestClient</c> used to instantiate the interface.
</p>
+
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<ja>@Remote</ja>(path=<js>"/petstore"</js>)
<jk>public interface</jk> PetStore {...}
</p>
<p class='bpcode w800'>
- RestClient client = RestClient.<jsm>create</jsm>().json().rootUrl(<js>"http://localhost:10000"</js>).build();
- PetStore p = client.getRemote(PetStore.<jk>class</jk>);
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
+ .json()
+ .rootUrl(<js>"http://localhost:10000"</js>)
+ .build();
+
+ PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>);
</p>
+
<p>
When no path is specified, the root-url defined on the <c>RestClient</c> is used.
</p>
+
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<ja>@Remote</ja>
<jk>public interface</jk> PetStore {...}
</p>
<p class='bpcode w800'>
- RestClient client = RestClient.<jsm>create</jsm>().json().rootUrl(<js>"http://localhost:10000/petstore"</js>).build();
- PetStore p = client.getRemote(PetStore.<jk>class</jk>);
+ RestClient <jv>client</jv> = RestClient
+ .<jsm>create</jsm>()
+ .json()
+ .rootUrl(<js>"http://localhost:10000/petstore"</js>)
+ .build();
+
+ PetStore <jv>store</jv> = <jv>client<jv>.getRemote(PetStore.<jk>class</jk>);
+</p>
+
+
+<h5 class='topic'>@Remote(headers/headerSupplier)</h5>
+<p>
+ The {@link org.apache.juneau.http.remote.Remote#headers @Remote(headers)} and {@link org.apache.juneau.http.remote.Remote#headerSupplier @Remote(headerSupplier)}
+ annotations are used to add headers on all requests.
+</p>
+
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <ja>@Remote</ja>(
+ path=<js>"/petstore"</js>,
+ headers={
+ <js>"Foo: bar"</js>,
+ <js>"Baz: $P{bazProperty}"</js>
+ },
+ headerSupplier=MyDynamicHeaderSupplier.<jk>class</jk>
+ )
+ <jk>public interface</jk> PetStore {...}
+</p>
+<p class='bpcode w800'>
+ <jc>// Our dynamic supplier.</jc>
+ <jk>public class</jk> MyHeaderSupplier <jk>extends</jk> HeaderSupplier {
+
+ <jc>// Headers can be added here at runtime.</jc>
+ <jk>public static</jk> HeaderSupplier <jsf>DYNAMIC_HEADERS</jsf> = <jk>new</jk> HeaderSupplier();
+
+ <jk>public</jk> MyHeaderSupplier() {
+ add(<js>"Qux"</js>,<js>"q2x"</js>);
+ add(<jsf>DYNAMIC_HEADERS</jsf>);
+ }
+ }
+</p>
+
+
+<h5 class='topic'>@Remote(version/versionHeader)</h5>
+<p>
+ The {@link org.apache.juneau.http.remote.Remote#version @Remote(version)} and {@link org.apache.juneau.http.remote.Remote#versionHeader @Remote(versionHeader)}
+ annotations are used to specify the client-side version of this interface that can be used on the server side
+ to perform version-specific handling.
+</p>
+<h5 class='figure'>Example:</h5>
+<p class='bpcode w800'>
+ <ja>@Remote</ja>(
+ path=<js>"/petstore"</js>,
+ version=<js>"1.2.3"</js> <jc>// Adds "X-Client-Version: 1.2.3" header to all requests.</jc>
+ )
+ <jk>public interface</jk> PetStore {...}
</p>
+
+<p>
+ This can be used in conjunction with the server-side client-versioning support.
+</p>
+<p class='bpcode w800'>
+ <jc>// Call this method if X-Client-Version is at least 2.0.
+ // Note that this also matches 2.0.1.</jc>
+ <ja>@RestMethod</ja>(clientVersion=<js>"2.0"</js>)
+ <jk>public</jk> Object getFoo() {...}
+
+ <jc>// Call this method if X-Client-Version is at least 1.1, but less than 2.0.</jc>
+ <ja>@RestMethod</ja>(clientVersion=<js>"[1.1,2.0)"</js>)
+ <jk>public</jk> Object getFoo() {...}
+
+ <jc>// Call this method if X-Client-Version is less than 1.1.</jc>
+ <ja>@RestMethod</ja>(clientVersion=<js>"[0,1.1)"</js>)
+ <jk>public</jk> Object getFoo() {...}
+</p>
+
+<ul class='seealso'>
+ <li class='doclink'>{@doc juneau-rest-server.ClientVersioning}
+</ul>
</div><!-- END: 9.11.1 - juneau-rest-client.RestProxies.Remote -->
<!-- ==================================================================================================== -->
@@ -23625,7 +23887,7 @@
<jc>// GET /pets/{petId}</jc>
<ja>@RemoteMethod</ja>(method=<js>"GET"</js>, path=<js>"/pets/{petId}"</js>)
- Pet getPet(<ja>@Path</ja>(<js>"petId"</js>) <jk>int</jk> id);
+ Pet getPet(<ja>@Path</ja>(<js>"petId"</js>) <jk>int</jk> <jv>id</jv>);
}
</p>
<p>
@@ -23767,7 +24029,7 @@
<li class='ja'>{@link org.apache.juneau.http.annotation.Body}
<ul>
<li class='jf'>{@link org.apache.juneau.http.annotation.Body#required() required} - Input validation. Body must be present.
- <li class='jf'>{@link org.apache.juneau.http.annotation.Body#schema() schema} - Swagger schema.
+ <li class='jf'>{@link org.apache.juneau.http.annotation.Body#schema() schema} - OpenAPI schema.
</ul>
</ul>
@@ -23778,7 +24040,7 @@
<jk>public interface</jk> PetStore {
<ja>@RemoteMethod</ja>(path=<js>"/pets"</js>)
- String addPet(<ja>@Body</ja> Pet pet);
+ String addPet(<ja>@Body</ja> Pet <jv>pet</jv>;
}
</p>
<p class='bpcode w800'>
@@ -23787,7 +24049,7 @@
<jk>public interface</jk> PetStore {
<ja>@RemoteMethod</ja>(path=<js>"/pets"</js>)
- String addPet(Pet pet);
+ String addPet(Pet <jv>pet</jv>);
}
<ja>@Body</ja>
@@ -23837,7 +24099,20 @@
)
)
)
- <jk>int</jk>[][] input
+ <jk>int</jk>[][] <jv>input</jv>
+ );
+</p>
+<p class='bpcode w800'>
+ <jc>// Same as above but using free-form schema.</jc>
+ <ja>@RemoteMethod</ja>(path=<js>"/comma-delimited-pipe-delimited-ints"</js>)
+ String addCommaDelimitedPipeDelimitedInts(
+ <ja>@Body</ja>(
+ serializer=OpenApiSerializer.<jk>class</jk>,
+ schema=<ja>@Schema</ja>(
+ <js>"type:'array,collectionFormat:'pipes',items:[type:'array',items:[type:'int32',minimum:0,maximum:64]]"</js>
+ )
+ )
+ <jk>int</jk>[][] <jv>input</jv>
);
</p>
<p>
@@ -23894,30 +24169,30 @@
<jc>// Explicit names specified for form data parameters.</jc>
<ja>@RemoteMethod</ja>
String postParameters(
- <ja>@FormData</ja>(<js>"foo"</js>)</ja> String foo,
- <ja>@FormData</ja>(<js>"bar"</js>)</ja> MyPojo pojo
+ <ja>@FormData</ja>(<js>"foo"</js>)</ja> String <jv>foo</jv>,
+ <ja>@FormData</ja>(<js>"bar"</js>)</ja> MyPojo <jv>pojo</jv>
);
<jc>// Multiple values pulled from a NameValuePairs object.</jc>
<jc>// Name "*" is inferred.</jc>
<ja>@RemoteMethod</ja>
- String postNameValuePairs(<ja>@FormData</ja> NameValuePairs nameValuePairs);
+ String postNameValuePairs(<ja>@FormData</ja> NameValuePairs <jv>nameValuePairs</jv>);
<jc>// Multiple values pulled from a Map.</jc>
<ja>@RemoteMethod</ja>
- String postMap(<ja>@FormData</ja> Map<String,Object> map);
+ String postMap(<ja>@FormData</ja> Map<String,Object> <jv>map</jv>);
<jc>// Multiple values pulled from a bean.</jc>
<ja>@RemoteMethod</ja>
- String postBean(<ja>@FormData</ja> MyBean bean);
+ String postBean(<ja>@FormData</ja> MyBean <jv>bean</jv>);
<jc>// An entire form-data HTTP body as a String.</jc>
<ja>@RemoteMethod</ja>
- String postString(<ja>@FormData</ja> String string);
+ String postString(<ja>@FormData</ja> String <jv>string</jv>);
<jc>// An entire form-data HTTP body as a Reader.</jc>
<ja>@RemoteMethod</ja>
- String postReader(<ja>@FormData</ja> Reader reader);
+ String postReader(<ja>@FormData</ja> Reader <jv>reader</jv>);
}
</p>
@@ -24001,33 +24276,33 @@
<jc>// Explicit names specified for query parameters.</jc>
<ja>@RemoteMethod</ja>
String parameters(
- <ja>@Query</ja>(<js>"foo"</js>)</ja> String foo,
- <ja>@Query</ja>(<js>"bar"</js>)</ja> MyPojo pojo);
+ <ja>@Query</ja>(<js>"foo"</js>)</ja> String <jv>foo</jv>,
+ <ja>@Query</ja>(<js>"bar"</js>)</ja> MyPojo <jv>pojo</jv>);
<jc>// Multiple values pulled from a NameValuePairs object.</jc>
<jc>// Same as @Query("*").</jc>
<ja>@RemoteMethod</ja>
- String nameValuePairs(<ja>@Query</ja> NameValuePairs nameValuePairs);
+ String nameValuePairs(<ja>@Query</ja> NameValuePairs <jv>nameValuePairs</jv>);
<jc>// Multiple values pulled from a Map.</jc>
<jc>// Same as @Query("*").</jc>
<ja>@RemoteMethod</ja>
- String map(<ja>@Query</ja> Map<String,Object> map);
+ String map(<ja>@Query</ja> Map<String,Object> <jv>map</jv>);
<jc>// Multiple values pulled from a bean.</jc>
<jc>// Same as @Query("*").</jc>
<ja>@RemoteMethod</ja>
- String bean(<ja>@Query</ja> MyBean myBean);
+ String bean(<ja>@Query</ja> MyBean <jv>myBean</jv>);
<jc>// An entire query string as a String.</jc>
<jc>// Same as @Query("*").</jc>
<ja>@RemoteMethod</ja>
- String string(<ja>@Query</ja> String string);
+ String string(<ja>@Query</ja> String <jv>string</jv>);
<jc>// An entire query string as a Reader.</jc>
<jc>// Same as @Query("*").</jc>
<ja>@RemoteMethod</ja>
- String reader(<ja>@Query</ja> Reader reader);
+ String reader(<ja>@Query</ja> Reader <jv>reader</jv>);
}
</p>
@@ -24111,23 +24386,23 @@
<jc>// Explicit names specified for HTTP headers.</jc>
<jc>// pojo will be converted to UON notation (unless plain-text parts enabled).</jc>
<ja>@RemoteMethod</ja>(path=<js>"/mymethod1"</js>)
- String myProxyMethod1(<ja>@Header</ja>(<js>"Foo"</js>)</ja> String foo,
- <ja>@Header</ja>(<js>"Bar"</js>)</ja> MyPojo pojo);
+ String myProxyMethod1(<ja>@Header</ja>(<js>"Foo"</js>)</ja> String <jv>foo</jv>,
+ <ja>@Header</ja>(<js>"Bar"</js>)</ja> MyPojo <jv>pojo</jv>);
<jc>// Multiple values pulled from a NameValuePairs object.</jc>
<jc>// Same as @Header("*").</jc>
<ja>@RemoteMethod</ja>(path=<js>"/mymethod2"</js>)
- String myProxyMethod2(<ja>@Header</ja> NameValuePairs nameValuePairs);
+ String myProxyMethod2(<ja>@Header</ja> NameValuePairs <jv>nameValuePairs</jv>);
<jc>// Multiple values pulled from a Map.</jc>
<jc>// Same as @Header("*").</jc>
<ja>@RemoteMethod</ja>(path=<js>"/mymethod3"</js>)
- String myProxyMethod3(<ja>@Header</ja> Map<String,Object> map);
+ String myProxyMethod3(<ja>@Header</ja> Map<String,Object> <jv>map</jv>);
<jc>// Multiple values pulled from a bean.</jc>
<jc>// Same as @Header("*").</jc>
<ja>@RemoteMethod</ja>(path=<js>"/mymethod4"</js>)
- String myProxyMethod4(<ja>@Header</ja> MyBean myBean);
+ String myProxyMethod4(<ja>@Header</ja> MyBean <jv>myBean</jv>);
}
</p>
@@ -24201,22 +24476,22 @@
<jc>// Explicit names specified for path parameters.</jc>
<jc>// pojo will be converted to UON notation (unless plain-text parts enabled).</jc>
<ja>@RemoteMethod</ja>(path=<js>"/mymethod1/{foo}/{bar}"</js>)
- String myProxyMethod1(<ja>@Path</ja>(<js>"foo"</js>)</ja> String foo, <ja>@Path</ja>(<js>"bar"</js>)</ja> MyPojo pojo);
+ String myProxyMethod1(<ja>@Path</ja>(<js>"foo"</js>)</ja> String <jv>foo</jv>, <ja>@Path</ja>(<js>"bar"</js>)</ja> MyPojo <jv>pojo</jv>);
<jc>// Multiple values pulled from a NameValuePairs object.</jc>
<jc>// Same as @Path("*").</jc>
<ja>@RemoteMethod</ja>(path=<js>"/mymethod2/{foo}/{bar}/{baz}"</js>)
- String myProxyMethod2(<ja>@Path</ja> NameValuePairs nameValuePairs);
+ String myProxyMethod2(<ja>@Path</ja> NameValuePairs <jv>nameValuePairs</jv>);
<jc>// Multiple values pulled from a Map.</jc>
<jc>// Same as @Path("*").</jc>
<ja>@RemoteMethod</ja>(path=<js>"/mymethod3/{foo}/{bar}/{baz}"</js>)
- String myProxyMethod3(<ja>@Path</ja> Map<String,Object> map);
+ String myProxyMethod3(<ja>@Path</ja> Map<String,Object> <jv>map</jv>);
<jc>// Multiple values pulled from a bean.</jc>
<jc>// Same as @Path("*").</jc>
<ja>@RemoteMethod</ja>(path=<js>"/mymethod4/{foo}/{bar}/{baz}"</js>)
- String myProxyMethod4(<ja>@Path</ja> MyBean myBean);
+ String myProxyMethod4(<ja>@Path</ja> MyBean <jv>myBean</jv>);
}
</p>
@@ -24275,7 +24550,7 @@
<jk>public interface</jk> PetStore {
<ja>@RemoteMethod</ja>
- String postPet(CreatePetRequest bean);
+ String postPet(CreatePetRequest <jv>bean</jv>);
}
</p>
<p class='bpcode w800'>
@@ -24284,8 +24559,8 @@
<jk>private</jk> CreatePet <jf>pet</jf>;
- <jk>public</jk> CreatePetRequest(String name, <jk>float</jk> price) {
- <jk>this</jk>.<jf>pet</jf> = <jk>new</jk> CreatePet(name, price);
+ <jk>public</jk> CreatePetRequest(String <jv>name</jv>, <jk>float</jk> <jv>price</jv>) {
+ <jk>this</jk>.<jf>pet</jf> = <jk>new</jk> CreatePet(<jv>name</jv>, <jv>price</jv>);
}
<ja>@Body</ja>
@@ -24295,7 +24570,7 @@
<ja>@Query</ja>
<jk>public</jk> Map<String,Object> getQueryParams() {
- <jk>return</jk> OMap.<jsm>of</jsm>(<js>"debug"</js>, <jk>true</jk>);
+ <jk>return</jk> AMap.<jsm>of</jsm>(<js>"debug"</js>, <jk>true</jk>);
}
<ja>@Header</ja>(<js>"E-Tag"</js>)
@@ -24305,9 +24580,10 @@
}
</p>
<p class='bpcode w800'>
- PetStore store = restClient.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
- CreatePetRequest requestBean = <jk>new</jk> CreatePetRequest(<js>"Fluffy"</js>, 9.99);
- String response = store.postPet(requestBean);
+ PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
+
+ CreatePetRequest <jv>requestBean</jv> = <jk>new</jk> CreatePetRequest(<js>"Fluffy"</js>, 9.99);
+ String <jv>response</jv> = <jv>store</jv>.postPet(requestBean);
</p>
<p>
The <ja>@Request</ja> annotation can be applied to either the class or argument.
@@ -24351,7 +24627,7 @@
<p class='bpcode w800'>
<jk>public class</jk> CreatePetRequestImpl <jk>implements</jk> CreatePetRequest {
- <jk>public</jk> CreatePetRequestImpl(String name, <jk>float</jk> price) {...}
+ <jk>public</jk> CreatePetRequestImpl(String <jv>name</jv>, <jk>float</jk> <jv>price</jv>) {...}
<ja>@Override</ja>
<jk>public</jk> CreatePet getBody() {
@@ -24407,15 +24683,16 @@
UUID getUUID();
<ja>@ResponseStatus</ja>
- int getStatus();
+ <jk>int</jk> getStatus();
}
</p>
<p class='bpcode w800'>
- PetStore store = restClient.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
- CreatePetResponse response = store.postPet(...);
- Pet pet = response.getBody();
- UUID uuid = response.getUUID();
- <jk>int</jk> status = response.getStatus();
+ PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
+
+ CreatePetResponse <jv>response</jv> = <jv>store</jv>.postPet(...);
+ Pet <jv>pet</jv> = <jv>response</jv>.getBody();
+ UUID <jv>uuid</jv> = <jv>response</jv>.getUUID();
+ <jk>int</jk> <jv>status</jv> = <jv>response</jv>.getStatus();
</p>
<p>
The annotated methods must be no-arg.
@@ -24468,13 +24745,13 @@
required=<jk>true</jk>,
example=<js>"foobar"</js>
)
- String apiKey,
+ String <jv>apiKey</jv>,
<ja>@Path</ja>(
name=<js>"petId"</js>,
description=<js>"Pet id to delete"</js>,
example=<js>"123"</js>
)
- <jk>long</jk> petId
+ <jk>long</jk> <jv>petId</jv>
) <jk>throws</jk> IdNotFound, NotAcceptable;
...
@@ -24510,8 +24787,8 @@
summary=<js>"Deletes a pet"</js>,
...
)
- <jk>public</jk> Ok deletePet(String apiKey, long petId) <jk>throws</jk> IdNotFound, NotAcceptable {
- <jsf>store</jsf>.removePet(petId);
+ <jk>public</jk> Ok deletePet(String <jv>apiKey</jv>, <jk>long</jk> <jv>petId</jv>) <jk>throws</jk> IdNotFound, NotAcceptable {
+ <jsf>store</jsf>.removePet(<jv>petId</jv>);
<jk>return</jk> <jsf>OK</jsf>;
}
</p>
@@ -24519,13 +24796,12 @@
Then use the interface as a remote resource like so:
</p>
<p class='bpcode w800'>
- <jk>try</jk> (RestClient rc = RestClient.<jsm>create</jsm>().json().rootUrl(<js>"http://localhost:10000"</js>).build()) {
- PetStore ps = rc.getRemote(PetStore.<jk>class</jk>);
+ RestClient client = RestClient.<jsm>create</jsm>().json().rootUrl(<js>"http://localhost:10000"</js>).build();
+ PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>);
- <jk>for</jk> (Pet x : ps.getPets()) {
- ps.deletePet(<js>"my-special-key"</js>, x.getId());
- System.<jsf>err</jsf>.println(<js>"Deleted pet: id="</js> + x.getId());
- }
+ <jk>for</jk> (Pet <jv>x</jv> : <jv>store</jv>.getPets()) {
+ <jv>store</jv>.deletePet(<js>"my-special-key"</js>, <jv>x</jv>.getId());
+ System.<jsf>err</jsf>.println(<js>"Deleted pet: id="</js> + <jv>x</jv>.getId());
}
</p>
<p>
@@ -24562,13 +24838,16 @@
<h5 class='figure'>Examples:</h5>
<p class='bpcode w800'>
- MyBean bean = RestClient
+ <jc>// A simple bean we're going to round-trip.</jc>
+ MyBean <jv>bean</jv> = <jk>new</jk> MyBean();
+
+ <jv>bean</jv> = RestClient
.<jsm>create</jsm>()
.simpleJson()
- .logRequests(DetailLevel.<jsf>FULL</jsf>, Level.<jsf>SEVERE</jsf>, (req,res)->req.getUri().endsWith(<js>"/bean"</js>))
+ .logRequests(DetailLevel.<jsf>FULL</jsf>, Level.<jsf>SEVERE</jsf>, (<jv>req</jv>,<jv>res</jv>)-><jv>req</jv>.getUri().endsWith(<js>"/bean"</js>))
.logToConsole()
.build()
- .post(<js>"http://localhost/bean"</js>, bean)
+ .post(<js>"http://localhost/bean"</js>, <jv>bean</jv>)
.run()
.getBody().as(MyBean.<jk>class</jk>);
</p>
@@ -24648,16 +24927,16 @@
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Create a client with customized HttpClient settings.</jc>
- MyBean bean = RestClient
+ MyBean <jv>bean</jv> = RestClient
.<jsm>create</jsm>()
.disableRedirectHandling()
- .connectionManager(myConnectionManager)
- .addInterceptorFirst(myHttpRequestInterceptor)
+ .connectionManager(<jv>myConnectionManager</jv>)
+ .addInterceptorFirst(<jv>myHttpRequestInterceptor</jv>)
.build();
</p>
<p>
- Refer to the {@link org.apache.http.client.impl.HttpClientBuilder HTTP Client Builder API} for more information.
+ Refer to the {@link org.apache.http.client.impl.HttpClientBuilder HttpClientBuilder} docs for more information.
</p>
</div><!-- END: 9.13 - juneau-rest-client.CustomizingHttpClient -->
@@ -24675,18 +24954,18 @@
<jk>public class</jk> MyRestClient <jk>extends</jk> RestClient {
<jc>// Must provide this constructor!</jc>
- <jk>public</jk> MyRestClient(PropertyStore ps) {
- <jk>super</jk>(ps);
+ <jk>public</jk> MyRestClient(PropertyStore <jv>ps</jv>) {
+ <jk>super</jk>(<jv>ps</jv>);
}
<ja>@Override</ja>
- <jk>public</jk> HttpResponse run(HttpHost target, HttpRequest request, HttpContext context) <jk>throws</jk> IOException {
+ <jk>public</jk> HttpResponse run(HttpHost <jv>target</jv>, HttpRequest <jv>request</jv>, HttpContext <jv>context</jv>) <jk>throws</jk> IOException {
<jc>// Perform special handling of requests.</jc>
}
}
<jc>// Instantiate your client.</jc>
- MyRestClient client = RestClient.<jsm>create</jsm>().json().build(MyRestClient.<jk>class</jk>);
+ MyRestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json().build(MyRestClient.<jk>class</jk>);
</p>
<p>
@@ -24719,7 +24998,7 @@
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
<jc>// Create a client that performs BASIC authentication using the specified user/pw.</jc>
- RestClient restClient = RestClient.<jsm>create</jsm>()
+ RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>()
.basicAuth(<jsf>HOST</jsf>, <jsf>PORT</jsf>, <jsf>USER</jsf>, <jsf>PW</jsf>)
.build();
</p>
@@ -24727,12 +25006,12 @@
This is functionally equivalent to the following:
</p>
<p class='bpcode w800'>
- RestClientBuilder builder = RestClient.<jsm>create</jsm>();
- AuthScope scope = <jk>new</jk> AuthScope(<jsf>HOST</jsf>, <jsf>PORT</jsf>);
- Credentials up = <jk>new</jk> UsernamePasswordCredentials(<jsf>USER</jsf>, <jsf>PW</jsf>);
- CredentialsProvider p = <jk>new</jk> BasicCredentialsProvider();
- p.setCredentials(scope, up);
- builder.setDefaultCredentialsProvider(p);
+ RestClientBuilder <jv>builder</jv> = RestClient.<jsm>create</jsm>();
+ AuthScope <jv>scope</jv> = <jk>new</jk> AuthScope(<jsf>HOST</jsf>, <jsf>PORT</jsf>);
+ Credentials <jv>up</jv> = <jk>new</jk> UsernamePasswordCredentials(<jsf>USER</jsf>, <jsf>PW</jsf>);
+ CredentialsProvider <jv>p</jv> = <jk>new</jk> BasicCredentialsProvider();
+ <jv>p</jv>.setCredentials(<jv>scope</jv>, <jv>up</jv>);
+ <jv>builder</jv>.setDefaultCredentialsProvider(<jv>p</jv>);
</p>
</div><!-- END: 9.15.1 - juneau-rest-client.Authentication.BASIC -->
@@ -24749,14 +25028,14 @@
authenticated client.
</p>
<p>
- The following example shows how the <c>JazzRestClient</c> class provides FORM-based
- authentication support.
+ The following example shows an implementation of a client that performs FORM-based authentication against
+ the IBM Jazz platform.
</p>
<p class='bpcode w800'>
<jd>/**
* Constructor.
*/</jd>
- <jk>public</jk> JazzRestClientBuilder(URI jazzUri, String user, String pw) <jk>throws</jk> IOException {
+ <jk>public</jk> JazzRestClientBuilder(URI <jv>jazzUri</jv>, String <jv>user</jv>, String <jv>pw</jv>) <jk>throws</jk> IOException {
...
}
@@ -24765,46 +25044,47 @@
*/</jd>
<ja>@Override</ja> <jc>/* RestClientBuilder */</jc>
<jk>protected</jk> CloseableHttpClient createHttpClient() <jk>throws</jk> Exception {
- CloseableHttpClient client = <jk>super</jk>.createHttpClient();
- formBasedAuthenticate(client);
- visitAuthenticatedURL(client);
- <jk>return</jk> client;
+ CloseableHttpClient <jv>client</jv> = <jk>super</jk>.createHttpClient();
+ formBasedAuthenticate(<jv>client</jv>);
+ visitAuthenticatedURL(<jv>client</jv>);
+ <jk>return</jk> <jv>client</jv>;
}
<jc>/*
* Performs form-based authentication against the Jazz server.
*/</jc>
- <jk>private void</jk> formBasedAuthenticate(HttpClient client) <jk>throws</jk> IOException {
+ <jk>private void</jk> formBasedAuthenticate(HttpClient <jv>client</jv>) <jk>throws</jk> IOException {
- URI uri2 = <jf>jazzUri</jf>.resolve(<js>"j_security_check"</js>);
- HttpPost request = <jk>new</jk> HttpPost(uri2);
- request.setConfig(RequestConfig.<jsm>custom</jsm>().setRedirectsEnabled(<jk>false</jk>).build());
+ URI <jv>uri2</jv> = <jf>jazzUri</jf>.resolve(<js>"j_security_check"</js>);
+ HttpPost <jv>request</jv> = <jk>new</jk> HttpPost(uri2);
+ <jv>request</jv>.setConfig(RequestConfig.<jsm>custom</jsm>().setRedirectsEnabled(<jk>false</jk>).build());
<jc>// Charset must explicitly be set to UTF-8 to handle user/pw with non-ascii characters.</jc>
- request.addHeader(<js>"Content-Type"</js>, <js>"application/x-www-form-urlencoded; charset=utf-8"</js>);
+ <jv>request</jv>.addHeader(<js>"Content-Type"</js>, <js>"application/x-www-form-urlencoded; charset=utf-8"</js>);
- NameValuePairs params = <jk>new</jk> NameValuePairs()
- .append(<jk>new</jk> BasicNameValuePair(<js>"j_username""</js>, <jf>user</jf>))
- .append(<jk>new</jk> BasicNameValuePair(<js>"j_password"</js>, <jf>pw</jf>));
- request.setEntity(<jk>new</jk> UrlEncodedFormEntity(params));
+ List<NameValuePair> <jv>params</jv> = AList.<jsm>of</jsm>(
+ BasicNameValuePair.<jsm>of</jsm>(<js>"j_username""</js>, <jf>user</jf>),
+ BasicNameValuePair.<jsm>of</jsm>(<js>"j_password"</js>, <jf>pw</jf>)
+ );
+ <jv>request</jv>.setEntity(<jk>new</jk> UrlEncodedFormEntity(<jv>params</jv>));
- HttpResponse response = client.execute(request);
+ HttpResponse <jv>response</jv> = <jv>client</jv>.execute(<jv>request</jv>);
<jk>try</jk> {
- <jk>int</jk> rc = response.getStatusLine().getStatusCode();
+ <jk>int</jk> <jv>rc</jv> = <jv>response</jv>.getStatusLine().getStatusCode();
- Header authMsg = response.getFirstHeader(<js>"X-com-ibm-team-repository-web-auth-msg"</js>);
- <jk>if</jk> (authMsg != <jk>null</jk>)
- <jk>throw new</jk> IOException(authMsg.getValue());
+ Header <jv>authMsg</jv> = <jv>response</jv>.getFirstHeader(<js>"X-com-ibm-team-repository-web-auth-msg"</js>);
+ <jk>if</jk> (<jv>authMsg</jv> != <jk>null</jk>)
+ <jk>throw new</jk> IOException(<jv>authMsg</jv>.getValue());
<jc>// The form auth request should always respond with a 200 ok or 302 redirect code</jc>
- <jk>if</jk> (rc == <jsf>SC_MOVED_TEMPORARILY</jsf>) {
- <jk>if</jk> (response.getFirstHeader(<js>"Location"</js>).getValue().matches(<js>"^.*/auth/authfailed.*$"</js>))
+ <jk>if</jk> (<jv>rc</jv> == <jsf>SC_MOVED_TEMPORARILY</jsf>) {
+ <jk>if</jk> (<jv>response</jv>.getFirstHeader(<js>"Location"</js>).getValue().matches(<js>"^.*/auth/authfailed.*$"</js>))
<jk>throw new</jk> IOException(<js>"Invalid credentials."</js>);
- } <jk>else if</jk> (rc != <jsf>SC_OK</jsf>) {
- <jk>throw new</jk> IOException(<js>"Unexpected HTTP status: "</js> + rc);
+ } <jk>else if</jk> (<jv>rc</jv> != <jsf>SC_OK</jsf>) {
+ <jk>throw new</jk> IOException(<js>"Unexpected HTTP status: "</js> + <jv>rc</jv>);
}
} <jk>finally</jk> {
- EntityUtils.<jsm>consume</jsm>(response.getEntity());
+ EntityUtils.<jsm>consume</jsm>(<jv>response</jv>.getEntity());
}
}
@@ -24813,13 +25093,13 @@
* authenticated URL has been visited. This same URL must also be visited after authenticating with j_security_check
* otherwise tomcat will not consider the session authenticated
*/</jc>
- <jk>private int</jk> visitAuthenticatedURL(HttpClient httpClient) <jk>throws</jk> IOException {
- HttpGet authenticatedURL = <jk>new</jk> HttpGet(<jf>jazzUri</jf>.resolve(<js>"authenticated/identity"</js>));
- HttpResponse response = httpClient.execute(authenticatedURL);
+ <jk>private int</jk> visitAuthenticatedURL(HttpClient <jv>httpClient</jv>) <jk>throws</jk> IOException {
+ HttpGet <jv>authenticatedURL</jv> = <jk>new</jk> HttpGet(<jf>jazzUri</jf>.resolve(<js>"authenticated/identity"</js>));
+ HttpResponse <jv>response</jv> = <jv>httpClient</jv>.execute(<jv>authenticatedURL</jv>);
<jk>try</jk> {
- <jk>return</jk> response.getStatusLine().getStatusCode();
+ <jk>return</jk> <jv>response</jv>.getStatusLine().getStatusCode();
} <jk>finally</jk> {
- EntityUtils.<jsm>consume</jsm>(response.getEntity());
+ EntityUtils.<jsm>consume</jsm>(<jv>response</jv>.getEntity());
}
}
</p>
@@ -24830,14 +25110,14 @@
<h4 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.Authentication.OIDC' id='juneau-rest-client.Authentication.OIDC'>9.15.3 - OIDC Authentication</a></h4>
<div class='topic'><!-- START: 9.15.3 - juneau-rest-client.Authentication.OIDC -->
<p>
- The following example shows how the <c>JazzRestClient</c> class provides OIDC authentication
- support.
+ The following example shows an implementation of a client that performs OIDC authentication against
+ the IBM Jazz platform.
</p>
<p class='bpcode w800'>
<jd>/**
* Constructor.
*/</jd>
- <jk>public</jk> JazzRestClientBuilder(URI jazzUri, String user, String pw) <jk>throws</jk> IOException {
+ <jk>public</jk> JazzRestClientBuilder(URI <jv>jazzUri</jv>, String <jv>user</jv>, String <jv>pw</jv>) <jk>throws</jk> IOException {
...
}
@@ -24846,108 +25126,108 @@
*/</jd>
<ja>@Override</ja> <jc>/* RestClientBuilder */</jc>
<jk>protected</jk> CloseableHttpClient createHttpClient() <jk>throws</jk> Exception {
- CloseableHttpClient client = <jk>super</jk>.createHttpClient();
- oidcAuthenticate(client);
- <jk>return</jk> client;
- }
+ CloseableHttpClient <jv>client</jv> = <jk>super</jk>.createHttpClient();
+ oidcAuthenticate(<jv>client</jv>);
+ <jk>return</jk> <jv>client</jv>;
+ }
- <jk>private void</jk> oidcAuthenticate(HttpClient client) <jk>throws</jk> IOException {
+ <jk>private void</jk> oidcAuthenticate(HttpClient <jv>client</jv>) <jk>throws</jk> IOException {
- HttpGet request = <jk>new</jk> HttpGet(<jf>jazzUri</jf>);
- request.setConfig(RequestConfig.<jsm>custom</jsm>().setRedirectsEnabled(<jk>false</jk>).build());
+ HttpGet <jv>request</jv> = <jk>new</jk> HttpGet(<jf>jazzUri</jf>);
+ <jv>request</jv>.setConfig(RequestConfig.<jsm>custom</jsm>().setRedirectsEnabled(<jk>false</jk>).build());
<jc>// Charset must explicitly be set to UTF-8 to handle user/pw with non-ascii characters.</jc>
- request.addHeader(<js>"Content-Type"</js>, <js>"application/x-www-form-urlencoded; charset=utf-8"</js>);
+ <jv>request</jv>.addHeader(<js>"Content-Type"</js>, <js>"application/x-www-form-urlencoded; charset=utf-8"</js>);
- HttpResponse response = client.execute(request);
+ HttpResponse <jv>response</jv> = <jv>client</jv>.execute(<jv>request</jv>);
<jk>try</jk> {
- <jk>int</jk> code = response.getStatusLine().getStatusCode();
+ <jk>int</jk> <jv>code</jv> = <jv>response</jv>.getStatusLine().getStatusCode();
<jc>// Already authenticated</jc>
- <jk>if</jk> (code == <jsf>SC_OK</jsf>)
+ <jk>if</jk> (<jv>code</jv> == <jsf>SC_OK</jsf>)
<jk>return</jk>;
- <jk>if</jk> (code != <jsf>SC_UNAUTHORIZED</jsf>)
+ <jk>if</jk> (<jv>code</jv> != <jsf>SC_UNAUTHORIZED</jsf>)
<jk>throw new</jk> RestCallException(<js>"Unexpected response during OIDC authentication: "</js>
- + response.getStatusLine());
+ + <jv>response</jv>.getStatusLine());
<jc>// x-jsa-authorization-redirect</jc>
- String redirectUri = getHeader(response, <js>"X-JSA-AUTHORIZATION-REDIRECT"</js>);
+ String <jv>redirectUri</jv> = getHeader(<jv>response</jv>, <js>"X-JSA-AUTHORIZATION-REDIRECT"</js>);
- <jk>if</jk> (redirectUri == <jk>null</jk>)
+ <jk>if</jk> (<jv>redirectUri</jv> == <jk>null</jk>)
<jk>throw new</jk> RestCallException(<js>"Expected a redirect URI during OIDC authentication: "</js>
- + response.getStatusLine());
+ + <jv>response</jv>.getStatusLine());
<jc>// Handle Bearer Challenge</jc>
- HttpGet method = <jk>new</jk> HttpGet(redirectUri + <js>"&prompt=none"</js>);
- addDefaultOidcHeaders(method);
+ HttpGet <jv>method</jv> = <jk>new</jk> HttpGet(<jv>redirectUri</jv> + <js>"&prompt=none"</js>);
+ addDefaultOidcHeaders(<jv>method</jv>);
- response = client.execute(method);
+ <jv>response</jv> = <jv>client</jv>.execute(<jv>method</jv>);
- code = response.getStatusLine().getStatusCode();
+ <jv>code</jv> = <jv>response</jv>.getStatusLine().getStatusCode();
- <jk>if</jk> (code != <jsf>SC_OK</jsf>)
+ <jk>if</jk> (<jv>code</jv> != <jsf>SC_OK</jsf>)
<jk>throw new</jk> RestCallException(<js>"Unexpected response during OIDC authentication phase 2: "</js>
- + response.getStatusLine());
+ + <jv>response</jv>.getStatusLine());
- String loginRequired = getHeader(response, <js>"X-JSA-LOGIN-REQUIRED"</js>);
+ String <jv>loginRequired</jv> = getHeader(<jv>response</jv>, <js>"X-JSA-LOGIN-REQUIRED"</js>);
- <jk>if</jk> (! <js>"true"</js>.equals(loginRequired))
+ <jk>if</jk> (! <js>"true"</js>.equals(<jv>loginRequired</jv>))
<jk>throw new</jk> RestCallException(<js>"X-JSA-LOGIN-REQUIRED header not found on response during OIDC authentication phase 2: "</js>
- + response.getStatusLine());
+ + <jv>response</jv>.getStatusLine());
- method = <jk>new</jk> HttpGet(redirectUri + <js>"&prompt=none"</js>);
+ <jv>method</jv> = <jk>new</jk> HttpGet(<jv>redirectUri</jv> + <js>"&prompt=none"</js>);
- addDefaultOidcHeaders(method);
- response = client.execute(method);
+ addDefaultOidcHeaders(<jv>method</jv>);
+ <jv>response</jv> = <jv>client</jv>.execute(<jv>method</jv>);
- code = response.getStatusLine().getStatusCode();
+ <jv>code</jv> = <jv>response</jv>.getStatusLine().getStatusCode();
- <jk>if</jk> (code != <jsf>SC_OK</jsf>)
+ <jk>if</jk> (<jv>code</jv> != <jsf>SC_OK</jsf>)
<jk>throw new</jk> RestCallException(<js>"Unexpected response during OIDC authentication phase 3: "</js>
- + response.getStatusLine());
+ + <jv>response</jv>.getStatusLine());
<jc>// Handle JAS Challenge</jc>
- method = <jk>new</jk> HttpGet(redirectUri);
- addDefaultOidcHeaders(method);
+ <jv>method</jv> = <jk>new</jk> HttpGet(<jv>redirectUri</jv>);
+ addDefaultOidcHeaders(<jv>method</jv>);
- response = client.execute(method);
+ <jv>response</jv> = <jv>client</jv>.execute(<jv>method</jv>);
- code = response.getStatusLine().getStatusCode();
+ <jv>code</jv> = <jv>response</jv>.getStatusLine().getStatusCode();
- <jk>if</jk> (code != <jsf>SC_OK</jsf>)
+ <jk>if</jk> (<jv>code</jv> != <jsf>SC_OK</jsf>)
<jk>throw new</jk> RestCallException(<js>"Unexpected response during OIDC authentication phase 4: "</js>
- + response.getStatusLine());
+ + <jv>response</jv>.getStatusLine());
- <jf>cookie</jf> = getHeader(response, <js>"Set-Cookie"</js>);
+ <jf>cookie</jf> = getHeader(<jv>response</jv>, <js>"Set-Cookie"</js>);
- Header[] defaultHeaders = <jk>new</jk> Header[] {
- <jk>new</jk> BasicHeader(<js>"User-Agent"</js>, <js>"Jazz Native Client"</js>),
- <jk>new</jk> BasicHeader(<js>"X-com-ibm-team-configuration-versions"</js>,
+ Header[] <jv>defaultHeaders</jv> = <jk>new</jk> Header[] {
+ BasicStringHeader.<jsm>of</jsm>(<js>"User-Agent"</js>, <js>"Jazz Native Client"</js>),
+ BasicStringHeader.<jsm>of</jsm>(<js>"X-com-ibm-team-configuration-versions"</js>,
<js>"com.ibm.team.rtc=6.0.0,com.ibm.team.jazz.foundation=6.0"</js>),
- <jk>new</jk> BasicHeader(<js>"Accept"</js>, <js>"text/json"</js>),
- <jk>new</jk> BasicHeader(<js>"Authorization"</js>, <js>"Basic "</js>
+ BasicStringHeader.<jsm>of</jsm>(<js>"Accept"</js>, <js>"text/json"</js>),
+ BasicStringHeader.<jsm>of</jsm>(<js>"Authorization"</js>, <js>"Basic "</js>
+ StringUtils.<jsm>base64EncodeToString</jsm>(<jf>user</jf> + <js>":"</js> + <jf>pw</jf>)),
- <jk>new</jk> BasicHeader(<js>"Cookie"</js>, cookie)
+ BasicStringHeader.<jsm>of</jsm>(<js>"Cookie"</js>, <jf>cookie</jf>)
};
- setDefaultHeaders(Arrays.<jsm>asList</jsm>(defaultHeaders));
+ setDefaultHeaders(AList.<jsm>of</jsm>(<jv>defaultHeaders</jv>));
} <jk>finally</jk> {
- EntityUtils.<jsm>consume</jsm>(response.getEntity());
+ EntityUtils.<jsm>consume</jsm>(<jv>response</jv>.getEntity());
}
}
- <jk>private void</jk> addDefaultOidcHeaders(HttpRequestBase method) {
- method.addHeader(<js>"User-Agent"</js>, <js>"Jazz Native Client"</js>);
- method.addHeader(<js>"X-com-ibm-team-configuration-versions"</js>,
+ <jk>private void</jk> addDefaultOidcHeaders(HttpRequestBase <jv>method</jv>) {
+ <jv>method</jv>.addHeader(<js>"User-Agent"</js>, <js>"Jazz Native Client"</js>);
+ <jv>method</jv>.addHeader(<js>"X-com-ibm-team-configuration-versions"</js>,
<js>"com.ibm.team.rtc=6.0.0,com.ibm.team.jazz.foundation=6.0"</js>);
- method.addHeader(<js>"Accept"</js>, <js>"text/json"</js>);
+ <jv>method</jv>.addHeader(<js>"Accept"</js>, <js>"text/json"</js>);
<jk>if</jk> (<jf>cookie</jf> != <jk>null</jk>) {
- method.addHeader(<js>"Authorization"</js>, <js>"Basic "</js>
+ <jv>method</jv>.addHeader(<js>"Authorization"</js>, <js>"Basic "</js>
+ StringUtils.<jsm>base64EncodeToString</jsm>(<jf>user</jf> + <js>":"</js> + <jf>pw</jf>));
- method.addHeader(<js>"Cookie"</js>, cookie);
+ <jv>method</jv>.addHeader(<js>"Cookie"</js>, <jf>cookie</jf>);
}
}
</p>
diff --git a/juneau-doc/src/main/javadoc/resources/fragments/toc.html b/juneau-doc/src/main/javadoc/resources/fragments/toc.html
index d9cdfdb..2c4cbb8 100644
--- a/juneau-doc/src/main/javadoc/resources/fragments/toc.html
+++ b/juneau-doc/src/main/javadoc/resources/fragments/toc.html
@@ -324,9 +324,9 @@
<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.ResponseBody'>Response Body</a><span class='update'><b>8.1.4-new</b></span></p>
<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.CustomCallHandlers'>Custom Call Handlers</a><span class='update'><b>8.1.4-new</b></span></p>
<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.Interceptors'>Interceptors</a><span class='update'><b>8.1.4-new</b></span></p>
- <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.RestProxies'>REST Proxies</a><span class='update'><b>8.1.4-new</b></span></p>
+ <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.RestProxies'>REST Proxies</a><span class='update'><b>8.1.4-updated</b></span></p>
<ol>
- <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.RestProxies.Remote'>@Remote</a><span class='update'>8.1.2-updated</span></p>
+ <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.RestProxies.Remote'>@Remote</a><span class='update'>8.1.2-updated,<b>8.1.4-updated</b></span></p>
<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.RestProxies.RemoteMethod'>@RemoteMethod</a><span class='update'><b>8.1.4-updated</b></span></p>
<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.RestProxies.Body'>@Body</a></p>
<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.RestProxies.FormData'>@FormData</a></p>
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/LargePojosResource.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/LargePojosResource.java
index ea16b80..56e56e0 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/LargePojosResource.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/LargePojosResource.java
@@ -33,7 +33,7 @@ public class LargePojosResource extends BasicRestServletJena {
//====================================================================================================
@RestMethod(name=GET, path="/")
public LargePojo testGet() {
- return LargePojo.create();
+ return LargePojo.get();
}
@RestMethod(name=PUT, path="/")
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyResource.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyResource.java
index 1b90a62..636df23 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyResource.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyResource.java
@@ -16,7 +16,8 @@ import static java.util.Arrays.*;
import static org.junit.Assert.*;
import static org.apache.juneau.assertions.Assertions.*;
import static org.apache.juneau.http.HttpMethodName.*;
-import static org.apache.juneau.rest.testutils.Constants.*;
+import static org.apache.juneau.testutils.Constants.*;
+
import java.io.*;
import java.util.*;
@@ -30,8 +31,8 @@ import org.apache.juneau.http.annotation.Path;
import org.apache.juneau.http.annotation.Query;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.testutils.*;
import org.apache.juneau.serializer.annotation.*;
+import org.apache.juneau.testutils.pojos.*;
/**
* JUnit automated testcase resource.
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyTest.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyTest.java
index e1c6990..7011c3e 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyTest.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyTest.java
@@ -13,7 +13,7 @@
package org.apache.juneau.rest.test.client;
import static org.apache.juneau.assertions.Assertions.*;
-import static org.apache.juneau.rest.testutils.Constants.*;
+import static org.apache.juneau.testutils.Constants.*;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.runners.MethodSorters.*;
@@ -34,8 +34,8 @@ import org.apache.juneau.parser.*;
import org.apache.juneau.http.remote.*;
import org.apache.juneau.rest.test.*;
import org.apache.juneau.rest.test.client.ThirdPartyProxyTest.ThirdPartyProxy.*;
-import org.apache.juneau.rest.testutils.*;
import org.apache.juneau.serializer.*;
+import org.apache.juneau.testutils.pojos.*;
import org.apache.juneau.uon.*;
import org.apache.juneau.urlencoding.*;
import org.apache.juneau.xml.*;
diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_FormDataAnnotation_Test.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_FormDataAnnotation_Test.java
index 93e227c..a2f2c38 100644
--- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_FormDataAnnotation_Test.java
+++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_FormDataAnnotation_Test.java
@@ -31,7 +31,7 @@ import org.apache.juneau.rest.RestRequest;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.http.remote.*;
import org.apache.juneau.rest.mock2.*;
-import org.apache.juneau.rest.testutils.*;
+import org.apache.juneau.testutils.*;
import org.apache.juneau.uon.*;
import org.apache.juneau.urlencoding.*;
import org.apache.juneau.utils.*;
diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_HeaderAnnotation_Test.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_HeaderAnnotation_Test.java
index 412348c..008f67a 100644
--- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_HeaderAnnotation_Test.java
+++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_HeaderAnnotation_Test.java
@@ -31,7 +31,7 @@ import org.apache.juneau.rest.RestRequest;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.http.remote.*;
import org.apache.juneau.rest.mock2.*;
-import org.apache.juneau.rest.testutils.*;
+import org.apache.juneau.testutils.*;
import org.apache.juneau.uon.*;
import org.junit.*;
diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_PathAnnotation_Test.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_PathAnnotation_Test.java
index 857a806..292421f 100644
--- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_PathAnnotation_Test.java
+++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_PathAnnotation_Test.java
@@ -30,7 +30,7 @@ import org.apache.juneau.rest.RestRequest;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.http.remote.*;
import org.apache.juneau.rest.mock2.*;
-import org.apache.juneau.rest.testutils.*;
+import org.apache.juneau.testutils.*;
import org.apache.juneau.uon.*;
import org.junit.*;
diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_QueryAnnotation_Test.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_QueryAnnotation_Test.java
index 204aaa3..4c0b834 100644
--- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_QueryAnnotation_Test.java
+++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_QueryAnnotation_Test.java
@@ -31,7 +31,7 @@ import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.RestRequest;
import org.apache.juneau.http.remote.*;
import org.apache.juneau.rest.mock2.*;
-import org.apache.juneau.rest.testutils.*;
+import org.apache.juneau.testutils.*;
import org.apache.juneau.uon.*;
import org.apache.juneau.utils.*;
import org.junit.*;
diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_RequestAnnotation_Test.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_RequestAnnotation_Test.java
index 58ccca9..f54dc76 100644
--- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_RequestAnnotation_Test.java
+++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/Remote_RequestAnnotation_Test.java
@@ -27,7 +27,7 @@ import org.apache.juneau.internal.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.http.remote.*;
import org.apache.juneau.rest.mock2.*;
-import org.apache.juneau.rest.testutils.*;
+import org.apache.juneau.testutils.*;
import org.junit.*;
@FixMethodOrder(NAME_ASCENDING)
diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RrpcInterfaceTest.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RrpcInterfaceTest.java
index c252aa4..22ea53e 100644
--- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RrpcInterfaceTest.java
+++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RrpcInterfaceTest.java
@@ -15,7 +15,7 @@ package org.apache.juneau.rest.client2;
import static java.util.Arrays.*;
import static org.apache.juneau.assertions.Assertions.*;
import static org.apache.juneau.http.HttpMethodName.*;
-import static org.apache.juneau.rest.testutils.Constants.*;
+import static org.apache.juneau.testutils.Constants.*;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.runners.MethodSorters.*;
@@ -31,9 +31,9 @@ import org.apache.juneau.parser.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.mock2.*;
-import org.apache.juneau.rest.testutils.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.serializer.annotation.*;
+import org.apache.juneau.testutils.pojos.*;
import org.apache.juneau.uon.*;
import org.apache.juneau.urlencoding.*;
import org.apache.juneau.xml.*;
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteMeta.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteMeta.java
index 5139191..5baddbd 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteMeta.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteMeta.java
@@ -22,6 +22,7 @@ import org.apache.juneau.http.*;
import org.apache.juneau.http.header.*;
import org.apache.juneau.http.remote.*;
import org.apache.juneau.reflect.*;
+import org.apache.juneau.svl.*;
/**
* Contains the meta-data about a REST proxy class.
@@ -37,7 +38,7 @@ import org.apache.juneau.reflect.*;
public class RemoteMeta {
private final Map<Method,RemoteMethodMeta> methods;
- private final HeaderSupplier headerSupplier = HeaderSupplier.create();
+ private final HeaderSupplier headerSupplier = HeaderSupplier.create().resolving();
/**
* Constructor.
@@ -55,13 +56,18 @@ public class RemoteMeta {
for (org.apache.juneau.http.remote.RemoteResource r : ci.getAnnotations(org.apache.juneau.http.remote.RemoteResource.class))
if (! r.path().isEmpty())
path = trimSlashes(r.path());
+
+ String versionHeader = "X-Client-Version", clientVersion = null;
+
for (Remote r : ci.getAnnotations(Remote.class)) {
if (! r.path().isEmpty())
- path = trimSlashes(r.path());
+ path = trimSlashes(resolve(r.path()));
for (String h : r.headers())
- headerSupplier.add(BasicHeader.ofPair(h));
+ headerSupplier.add(BasicHeader.ofPair(resolve(h)));
if (! r.version().isEmpty())
- headerSupplier.add(ClientVersion.of(r.version()));
+ clientVersion = resolve(r.version());
+ if (! r.versionHeader().isEmpty())
+ versionHeader = resolve(r.versionHeader());
if (r.headerSupplier() != HeaderSupplier.Null.class) {
try {
headerSupplier.add(r.headerSupplier().newInstance());
@@ -71,6 +77,9 @@ public class RemoteMeta {
}
}
+ if (clientVersion != null)
+ headerSupplier.add(BasicStringHeader.of(versionHeader, clientVersion));
+
AMap<Method,RemoteMethodMeta> methods = AMap.of();
for (MethodInfo m : ci.getPublicMethods())
methods.put(m.inner(), new RemoteMethodMeta(path, m.inner(), "GET"));
@@ -96,4 +105,12 @@ public class RemoteMeta {
public Iterable<Header> getHeaders() {
return headerSupplier;
}
+
+ //------------------------------------------------------------------------------------------------------------------
+ // Helper methods.
+ //------------------------------------------------------------------------------------------------------------------
+
+ private static String resolve(String s) {
+ return VarResolver.DEFAULT.resolve(s);
+ }
}
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
index a2b1bdf..9332b7b 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
@@ -1202,7 +1202,7 @@ public class RestClient extends BeanContext implements HttpClient, Closeable, Re
* String <jv>body</jv> = <jv>responseFuture</jv>.get().getBody().asString();
*
* <jc>// Use it to asynchronously retrieve a response.</jc>
- * Future<MyBean>l <jv>myBeanFuture</jv> = <jv>client</jv>
+ * Future<MyBean> <jv>myBeanFuture</jv> = <jv>client</jv>
* .get(<jsf>URI</jsf>)
* .run()
* .getBody().asFuture(MyBean.<jk>class</jk>);
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClientBuilder.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClientBuilder.java
index a81ce7a..6951e4f 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClientBuilder.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClientBuilder.java
@@ -2554,7 +2554,7 @@ public class RestClientBuilder extends BeanContextBuilder {
* String <jv>body</jv> = <jv>responseFuture</jv>.get().getBody().asString();
*
* <jc>// Use it to asynchronously retrieve a response.</jc>
- * Future<MyBean>l <jv>myBeanFuture</jv> = <jv>client</jv>
+ * Future<MyBean> <jv>myBeanFuture</jv> = <jv>client</jv>
* .get(<jsf>URI</jsf>)
* .run()
* .getBody().asFuture(MyBean.<jk>class</jk>);
diff --git a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/ABean.java b/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/ABean.java
deleted file mode 100644
index ce66ddb..0000000
--- a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/ABean.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// ***************************************************************************************************************************
-// * 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.testutils;
-
-import org.apache.juneau.marshall.*;
-
-public class ABean {
- public int a;
- public String b;
-
- public static ABean get() {
- ABean x = new ABean();
- x.a = 1;
- x.b = "foo";
- return x;
- }
-
- @Override
- public String toString() {
- return SimpleJson.DEFAULT.toString(this);
- }
-}
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/DTOs.java b/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/DTOs.java
deleted file mode 100644
index fe1d1c4..0000000
--- a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/DTOs.java
+++ /dev/null
@@ -1,142 +0,0 @@
-// ***************************************************************************************************************************
-// * 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.testutils;
-
-import java.util.*;
-
-import org.apache.juneau.annotation.*;
-import org.apache.juneau.collections.*;
-import org.apache.juneau.urlencoding.annotation.*;
-
-public class DTOs {
-
- @Bean(sort=true)
- public static class A {
- public String a;
- public int b;
- public boolean c;
-
- public static A get() {
- A t = new A();
- t.a = "a";
- t.b = 1;
- t.c = true;
- return t;
- }
-
- }
-
- @Bean(sort=true)
- public static class B {
- public String[] f01;
- public List<String> f02;
- public int[] f03;
- public List<Integer> f04;
- public String[][] f05;
- public List<String[]> f06;
- public A[] f07;
- public List<A> f08;
- public A[][] f09;
- public List<List<A>> f10;
-
- private String[] f11;
- private List<String> f12;
- private int[] f13;
- private List<Integer> f14;
- private String[][] f15;
- private List<String[]> f16;
- private A[] f17;
- private List<A> f18;
- private A[][] f19;
- private List<List<A>> f20;
-
- public String[] getF11() { return f11; }
- public List<String> getF12() { return f12; }
- public int[] getF13() { return f13; }
- public List<Integer> getF14() { return f14; }
- public String[][] getF15() { return f15; }
- public List<String[]> getF16() { return f16; }
- public A[] getF17() { return f17; }
- public List<A> getF18() { return f18; }
- public A[][] getF19() { return f19; }
- public List<List<A>> getF20() { return f20; }
-
- public void setF11(String[] f11) { this.f11 = f11; }
- public void setF12(List<String> f12) { this.f12 = f12; }
- public void setF13(int[] f13) { this.f13 = f13; }
- public void setF14(List<Integer> f14) { this.f14 = f14; }
- public void setF15(String[][] f15) { this.f15 = f15; }
- public void setF16(List<String[]> f16) { this.f16 = f16; }
- public void setF17(A[] f17) { this.f17 = f17; }
- public void setF18(List<A> f18) { this.f18 = f18; }
- public void setF19(A[][] f19) { this.f19 = f19; }
- public void setF20(List<List<A>> f20) { this.f20 = f20; }
-
- public static B get() {
- B t = new B();
- t.f01 = new String[]{"a","b"};
- t.f02 = AList.of("c","d");
- t.f03 = new int[]{1,2};
- t.f04 = AList.of(3,4);
- t.f05 = new String[][]{{"e","f"},{"g","h"}};
- t.f06 = AList.of(new String[]{"i","j"},new String[]{"k","l"});
- t.f07 = new A[]{A.get(),A.get()};
- t.f08 = AList.of(A.get(),A.get());
- t.f09 = new A[][]{{A.get()},{A.get()}};
- t.f10 = AList.of(Arrays.asList(A.get()),Arrays.asList(A.get()));
- t.setF11(new String[]{"a","b"});
- t.setF12(AList.of("c","d"));
- t.setF13(new int[]{1,2});
- t.setF14(AList.of(3,4));
- t.setF15(new String[][]{{"e","f"},{"g","h"}});
- t.setF16(AList.of(new String[]{"i","j"},new String[]{"k","l"}));
- t.setF17(new A[]{A.get(),A.get()});
- t.setF18(AList.of(A.get(),A.get()));
- t.setF19(new A[][]{{A.get()},{A.get()}});
- t.setF20(AList.of(Arrays.asList(A.get()),Arrays.asList(A.get())));
- return t;
- }
-
- public static B INSTANCE = get();
- }
-
- @UrlEncoding(expandedParams=true)
- public static class C extends B {
- public static C get() {
- C t = new C();
- t.f01 = new String[]{"a","b"};
- t.f02 = AList.of("c","d");
- t.f03 = new int[]{1,2};
- t.f04 = AList.of(3, 4);
- t.f05 = new String[][]{{"e","f"},{"g","h"}};
- t.f06 = AList.of(new String[]{"i","j"}, new String[]{"k","l"});
- t.f07 = new A[]{A.get(),A.get()};
- t.f08 = AList.of(A.get(), A.get());
- t.f09 = new A[][]{{A.get()},{A.get()}};
- t.f10 = AList.of(Arrays.asList(A.get()), Arrays.asList(A.get()));
- t.setF11(new String[]{"a","b"});
- t.setF12(AList.of("c","d"));
- t.setF13(new int[]{1,2});
- t.setF14(AList.of(3,4));
- t.setF15(new String[][]{{"e","f"},{"g","h"}});
- t.setF16(AList.of(new String[]{"i","j"},new String[]{"k","l"}));
- t.setF17(new A[]{A.get(),A.get()});
- t.setF18(AList.of(A.get(), A.get()));
- t.setF19(new A[][]{{A.get()},{A.get()}});
- t.setF20(AList.of(Arrays.asList(A.get()), Arrays.asList(A.get())));
- return t;
- }
-
- public static C INSTANCE = get();
- }
-}
diff --git a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/DTOs2.java b/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/DTOs2.java
deleted file mode 100644
index e84d0f8..0000000
--- a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/DTOs2.java
+++ /dev/null
@@ -1,143 +0,0 @@
-// ***************************************************************************************************************************
-// * 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.testutils;
-
-import java.util.*;
-
-import org.apache.juneau.annotation.*;
-import org.apache.juneau.collections.*;
-import org.apache.juneau.urlencoding.annotation.*;
-
-public class DTOs2 {
-
- @BeanConfig(applyBean={@Bean(on="A,B,C",sort=true)})
- @UrlEncodingConfig(applyUrlEncoding={@UrlEncoding(on="C",expandedParams=true)})
- public static class Annotations {}
-
- public static class A {
- public String a;
- public int b;
- public boolean c;
-
- public static A get() {
- A t = new A();
- t.a = "a";
- t.b = 1;
- t.c = true;
- return t;
- }
-
- }
-
- public static class B {
- public String[] f01;
- public List<String> f02;
- public int[] f03;
- public List<Integer> f04;
- public String[][] f05;
- public List<String[]> f06;
- public A[] f07;
- public List<A> f08;
- public A[][] f09;
- public List<List<A>> f10;
-
- private String[] f11;
- private List<String> f12;
- private int[] f13;
- private List<Integer> f14;
- private String[][] f15;
- private List<String[]> f16;
- private A[] f17;
- private List<A> f18;
- private A[][] f19;
- private List<List<A>> f20;
-
- public String[] getF11() { return f11; }
- public List<String> getF12() { return f12; }
- public int[] getF13() { return f13; }
- public List<Integer> getF14() { return f14; }
- public String[][] getF15() { return f15; }
- public List<String[]> getF16() { return f16; }
- public A[] getF17() { return f17; }
- public List<A> getF18() { return f18; }
- public A[][] getF19() { return f19; }
- public List<List<A>> getF20() { return f20; }
-
- public void setF11(String[] f11) { this.f11 = f11; }
- public void setF12(List<String> f12) { this.f12 = f12; }
- public void setF13(int[] f13) { this.f13 = f13; }
- public void setF14(List<Integer> f14) { this.f14 = f14; }
- public void setF15(String[][] f15) { this.f15 = f15; }
- public void setF16(List<String[]> f16) { this.f16 = f16; }
- public void setF17(A[] f17) { this.f17 = f17; }
- public void setF18(List<A> f18) { this.f18 = f18; }
- public void setF19(A[][] f19) { this.f19 = f19; }
- public void setF20(List<List<A>> f20) { this.f20 = f20; }
-
- public static B get() {
- B t = new B();
- t.f01 = new String[]{"a","b"};
- t.f02 = AList.of("c","d");
- t.f03 = new int[]{1,2};
- t.f04 = AList.of(3,4);
- t.f05 = new String[][]{{"e","f"},{"g","h"}};
- t.f06 = AList.of(new String[]{"i","j"},new String[]{"k","l"});
- t.f07 = new A[]{A.get(),A.get()};
- t.f08 = AList.of(A.get(),A.get());
- t.f09 = new A[][]{{A.get()},{A.get()}};
- t.f10 = AList.of(Arrays.asList(A.get()),Arrays.asList(A.get()));
- t.setF11(new String[]{"a","b"});
- t.setF12(AList.of("c","d"));
- t.setF13(new int[]{1,2});
- t.setF14(AList.of(3,4));
- t.setF15(new String[][]{{"e","f"},{"g","h"}});
- t.setF16(AList.of(new String[]{"i","j"},new String[]{"k","l"}));
- t.setF17(new A[]{A.get(),A.get()});
- t.setF18(AList.of(A.get(),A.get()));
- t.setF19(new A[][]{{A.get()},{A.get()}});
- t.setF20(AList.of(Arrays.asList(A.get()),Arrays.asList(A.get())));
- return t;
- }
-
- public static B INSTANCE = get();
- }
-
- public static class C extends B {
- public static C get() {
- C t = new C();
- t.f01 = new String[]{"a","b"};
- t.f02 = AList.of("c","d");
- t.f03 = new int[]{1,2};
- t.f04 = AList.of(3, 4);
- t.f05 = new String[][]{{"e","f"},{"g","h"}};
- t.f06 = AList.of(new String[]{"i","j"}, new String[]{"k","l"});
- t.f07 = new A[]{A.get(),A.get()};
- t.f08 = AList.of(A.get(), A.get());
- t.f09 = new A[][]{{A.get()},{A.get()}};
- t.f10 = AList.of(Arrays.asList(A.get()), Arrays.asList(A.get()));
- t.setF11(new String[]{"a","b"});
- t.setF12(AList.of("c","d"));
- t.setF13(new int[]{1,2});
- t.setF14(AList.of(3,4));
- t.setF15(new String[][]{{"e","f"},{"g","h"}});
- t.setF16(AList.of(new String[]{"i","j"},new String[]{"k","l"}));
- t.setF17(new A[]{A.get(),A.get()});
- t.setF18(AList.of(A.get(), A.get()));
- t.setF19(new A[][]{{A.get()},{A.get()}});
- t.setF20(AList.of(Arrays.asList(A.get()), Arrays.asList(A.get())));
- return t;
- }
-
- public static C INSTANCE = get();
- }
-}
diff --git a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/ImplicitSwappedPojo.java b/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/ImplicitSwappedPojo.java
deleted file mode 100644
index e65cee4..0000000
--- a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/ImplicitSwappedPojo.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// ***************************************************************************************************************************
-// * 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.testutils;
-
-import static org.apache.juneau.rest.testutils.Constants.*;
-
-import org.apache.juneau.annotation.*;
-
-@BeanIgnore
-public class ImplicitSwappedPojo {
- public boolean wasUnswapped;
-
- @Override
- public String toString() {
- return SWAP;
- }
-
- public ImplicitSwappedPojo() {}
-
-
- public ImplicitSwappedPojo(String fromString) {
- if (fromString.equals(SWAP))
- wasUnswapped = true;
- }
-}
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/SwappedPojo.java b/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/SwappedPojo.java
deleted file mode 100644
index 17d3249..0000000
--- a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/SwappedPojo.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// ***************************************************************************************************************************
-// * 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.testutils;
-
-import org.apache.juneau.annotation.*;
-
-@Swap(SwappedPojoSwap.class)
-public class SwappedPojo {
- public boolean wasUnswapped;
-}
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/SwappedPojoSwap.java b/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/SwappedPojoSwap.java
deleted file mode 100644
index ffae878..0000000
--- a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/SwappedPojoSwap.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// ***************************************************************************************************************************
-// * 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.testutils;
-
-import static org.apache.juneau.rest.testutils.Constants.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.parser.*;
-import org.apache.juneau.serializer.*;
-import org.apache.juneau.transform.*;
-
-public class SwappedPojoSwap extends PojoSwap<SwappedPojo,String> {
- @Override
- public String swap(BeanSession session, SwappedPojo c) throws SerializeException {
- return SWAP;
- }
-
- @Override
- public SwappedPojo unswap(BeanSession session, String f, ClassMeta<?> hint) throws ParseException {
- SwappedPojo c = new SwappedPojo();
- if (f.equals(SWAP))
- c.wasUnswapped = true;
- return c;
- }
-}
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/TestEnum.java b/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/TestEnum.java
deleted file mode 100644
index c869f53..0000000
--- a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/TestEnum.java
+++ /dev/null
@@ -1,17 +0,0 @@
-// ***************************************************************************************************************************
-// * 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.testutils;
-
-public enum TestEnum {
- ONE,TWO,THREE
-}
diff --git a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/TypedBean.java b/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/TypedBean.java
deleted file mode 100644
index 078ce88..0000000
--- a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/TypedBean.java
+++ /dev/null
@@ -1,17 +0,0 @@
-// ***************************************************************************************************************************
-// * 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.testutils;
-
-@org.apache.juneau.annotation.Bean(dictionary={TypedBeanImpl.class})
-public interface TypedBean {
-}
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/TypedBeanImpl.java b/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/TypedBeanImpl.java
deleted file mode 100644
index 95f0352..0000000
--- a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/TypedBeanImpl.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// ***************************************************************************************************************************
-// * 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.testutils;
-
-@org.apache.juneau.annotation.Bean(typeName="TypedBeanImpl", sort=true)
-public class TypedBeanImpl implements TypedBean {
- public int a;
- public String b;
-
- public static TypedBeanImpl get() {
- TypedBeanImpl x = new TypedBeanImpl();
- x.a = 1;
- x.b = "foo";
- return x;
- }
-}
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/BodyAnnotationTest.java b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/BodyAnnotationTest.java
index 4bc2591..f055ac5 100644
--- a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/BodyAnnotationTest.java
+++ b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/BodyAnnotationTest.java
@@ -33,9 +33,7 @@ import org.apache.juneau.jsonschema.annotation.*;
import org.apache.juneau.marshall.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.mock2.*;
-import org.apache.juneau.rest.testutils.*;
-import org.apache.juneau.rest.testutils.DTOs;
-import org.apache.juneau.rest.testutils.DTOs2;
+import org.apache.juneau.testutils.pojos.*;
import org.apache.juneau.uon.*;
import org.apache.juneau.urlencoding.*;
import org.apache.juneau.urlencoding.annotation.*;
@@ -849,11 +847,11 @@ public class BodyAnnotationTest {
@Rest(serializers=SimpleJsonSerializer.class, parsers=JsonParser.class, defaultAccept="application/json")
public static class E {
@RestMethod(name=PUT, path="/B")
- public DTOs.B testPojo1(@Body DTOs.B b) {
+ public XBeans.XB testPojo1(@Body XBeans.XB b) {
return b;
}
@RestMethod(name=PUT, path="/C")
- public DTOs.C testPojo2(@Body DTOs.C c) {
+ public XBeans.XC testPojo2(@Body XBeans.XC c) {
return c;
}
}
@@ -862,28 +860,28 @@ public class BodyAnnotationTest {
@Test
public void e01_complexPojos_B_body() throws Exception {
String expected = "{f01:['a','b'],f02:['c','d'],f03:[1,2],f04:[3,4],f05:[['e','f'],['g','h']],f06:[['i','j'],['k','l']],f07:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f08:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f09:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f10:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f11:['a','b'],f12:['c','d'],f13:[1,2],f14:[3,4],f15:[['e','f'],['g','h']],f16:[['i','j'],['k','l']],f17:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f18:[{a:'a',b:1,c:true},{a:'a',b:1,c:true} [...]
- e.put("/B", SimpleJsonSerializer.DEFAULT.toString(DTOs.B.INSTANCE), "application/json")
+ e.put("/B", SimpleJsonSerializer.DEFAULT.toString(XBeans.XB.INSTANCE), "application/json")
.run()
.assertBody().is(expected);
}
@Test
public void e02_complexPojos_B_bodyParam() throws Exception {
String expected = "{f01:['a','b'],f02:['c','d'],f03:[1,2],f04:[3,4],f05:[['e','f'],['g','h']],f06:[['i','j'],['k','l']],f07:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f08:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f09:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f10:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f11:['a','b'],f12:['c','d'],f13:[1,2],f14:[3,4],f15:[['e','f'],['g','h']],f16:[['i','j'],['k','l']],f17:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f18:[{a:'a',b:1,c:true},{a:'a',b:1,c:true} [...]
- e.put("/B?body=" + UonSerializer.DEFAULT.serialize(DTOs.B.INSTANCE), "a")
+ e.put("/B?body=" + UonSerializer.DEFAULT.serialize(XBeans.XB.INSTANCE), "a")
.run()
.assertBody().is(expected);
}
@Test
public void e03_complexPojos_C_body() throws Exception {
String expected = "{f01:['a','b'],f02:['c','d'],f03:[1,2],f04:[3,4],f05:[['e','f'],['g','h']],f06:[['i','j'],['k','l']],f07:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f08:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f09:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f10:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f11:['a','b'],f12:['c','d'],f13:[1,2],f14:[3,4],f15:[['e','f'],['g','h']],f16:[['i','j'],['k','l']],f17:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f18:[{a:'a',b:1,c:true},{a:'a',b:1,c:true} [...]
- e.put("/C", SimpleJsonSerializer.DEFAULT.toString(DTOs.B.INSTANCE), "application/json")
+ e.put("/C", SimpleJsonSerializer.DEFAULT.toString(XBeans.XB.INSTANCE), "application/json")
.run()
.assertBody().is(expected);
}
@Test
public void e04_complexPojos_C_bodyParam() throws Exception {
String expected = "{f01:['a','b'],f02:['c','d'],f03:[1,2],f04:[3,4],f05:[['e','f'],['g','h']],f06:[['i','j'],['k','l']],f07:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f08:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f09:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f10:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f11:['a','b'],f12:['c','d'],f13:[1,2],f14:[3,4],f15:[['e','f'],['g','h']],f16:[['i','j'],['k','l']],f17:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f18:[{a:'a',b:1,c:true},{a:'a',b:1,c:true} [...]
- e.put("/C?body=" + UonSerializer.DEFAULT.serialize(DTOs.B.INSTANCE), "a")
+ e.put("/C?body=" + UonSerializer.DEFAULT.serialize(XBeans.XB.INSTANCE), "a")
.run()
.assertBody().is(expected);
}
@@ -893,11 +891,11 @@ public class BodyAnnotationTest {
@UrlEncodingConfig(applyUrlEncoding={@UrlEncoding(on="C",expandedParams=true)})
public static class E2 {
@RestMethod(name=PUT, path="/B")
- public DTOs2.B testPojo1(@Body DTOs2.B b) {
+ public XBeans.XE testPojo1(@Body XBeans.XE b) {
return b;
}
@RestMethod(name=PUT, path="/C")
- public DTOs2.C testPojo2(@Body DTOs2.C c) {
+ public XBeans.XF testPojo2(@Body XBeans.XF c) {
return c;
}
}
@@ -906,28 +904,28 @@ public class BodyAnnotationTest {
@Test
public void e05_complexPojos_B_body() throws Exception {
String expected = "{f01:['a','b'],f02:['c','d'],f03:[1,2],f04:[3,4],f05:[['e','f'],['g','h']],f06:[['i','j'],['k','l']],f07:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f08:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f09:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f10:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f11:['a','b'],f12:['c','d'],f13:[1,2],f14:[3,4],f15:[['e','f'],['g','h']],f16:[['i','j'],['k','l']],f17:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f18:[{a:'a',b:1,c:true},{a:'a',b:1,c:true} [...]
- e2.put("/B", SimpleJsonSerializer.DEFAULT.builder().applyAnnotations(DTOs2.Annotations.class).build().toString(DTOs2.B.INSTANCE), "application/json")
+ e2.put("/B", SimpleJsonSerializer.DEFAULT.builder().applyAnnotations(XBeans.Annotations.class).build().toString(XBeans.XE.INSTANCE), "application/json")
.run()
.assertBody().is(expected);
}
@Test
public void e06_complexPojos_B_bodyParam() throws Exception {
String expected = "{f01:['a','b'],f02:['c','d'],f03:[1,2],f04:[3,4],f05:[['e','f'],['g','h']],f06:[['i','j'],['k','l']],f07:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f08:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f09:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f10:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f11:['a','b'],f12:['c','d'],f13:[1,2],f14:[3,4],f15:[['e','f'],['g','h']],f16:[['i','j'],['k','l']],f17:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f18:[{a:'a',b:1,c:true},{a:'a',b:1,c:true} [...]
- e2.put("/B?body=" + UonSerializer.DEFAULT.builder().applyAnnotations(DTOs2.Annotations.class).build().serialize(DTOs2.B.INSTANCE), "a")
+ e2.put("/B?body=" + UonSerializer.DEFAULT.builder().applyAnnotations(XBeans.Annotations.class).build().serialize(XBeans.XE.INSTANCE), "a")
.run()
.assertBody().is(expected);
}
@Test
public void e07_complexPojos_C_body() throws Exception {
String expected = "{f01:['a','b'],f02:['c','d'],f03:[1,2],f04:[3,4],f05:[['e','f'],['g','h']],f06:[['i','j'],['k','l']],f07:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f08:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f09:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f10:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f11:['a','b'],f12:['c','d'],f13:[1,2],f14:[3,4],f15:[['e','f'],['g','h']],f16:[['i','j'],['k','l']],f17:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f18:[{a:'a',b:1,c:true},{a:'a',b:1,c:true} [...]
- e2.put("/C", SimpleJsonSerializer.DEFAULT.builder().applyAnnotations(DTOs2.Annotations.class).build().toString(DTOs2.B.INSTANCE), "application/json")
+ e2.put("/C", SimpleJsonSerializer.DEFAULT.builder().applyAnnotations(XBeans.Annotations.class).build().toString(XBeans.XE.INSTANCE), "application/json")
.run()
.assertBody().is(expected);
}
@Test
public void e08_complexPojos_C_bodyParam() throws Exception {
String expected = "{f01:['a','b'],f02:['c','d'],f03:[1,2],f04:[3,4],f05:[['e','f'],['g','h']],f06:[['i','j'],['k','l']],f07:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f08:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f09:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f10:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f11:['a','b'],f12:['c','d'],f13:[1,2],f14:[3,4],f15:[['e','f'],['g','h']],f16:[['i','j'],['k','l']],f17:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f18:[{a:'a',b:1,c:true},{a:'a',b:1,c:true} [...]
- e2.put("/C?body=" + UonSerializer.DEFAULT.builder().applyAnnotations(DTOs2.Annotations.class).build().serialize(DTOs2.B.INSTANCE), "a")
+ e2.put("/C?body=" + UonSerializer.DEFAULT.builder().applyAnnotations(XBeans.Annotations.class).build().serialize(XBeans.XE.INSTANCE), "a")
.run()
.assertBody().is(expected);
}
@@ -977,7 +975,7 @@ public class BodyAnnotationTest {
@Rest(serializers=UrlEncodingSerializer.class,parsers=UrlEncodingParser.class)
public static class G {
@RestMethod(name=POST,path="/")
- public DTOs.C g(@Body DTOs.C content) throws Exception {
+ public XBeans.XC g(@Body XBeans.XC content) throws Exception {
return content;
}
}
@@ -1025,7 +1023,7 @@ public class BodyAnnotationTest {
@Property(name=UrlEncodingParser.URLENC_expandedParams, value="true")
}
)
- public DTOs.B g(@Body DTOs.B content) throws Exception {
+ public XBeans.XB g(@Body XBeans.XB content) throws Exception {
return content;
}
}
@@ -1069,7 +1067,7 @@ public class BodyAnnotationTest {
@Property(name=UrlEncodingParser.URLENC_expandedParams, value="true")
}
)
- public DTOs2.B g(@Body DTOs2.B content) throws Exception {
+ public XBeans.XE g(@Body XBeans.XE content) throws Exception {
return content;
}
}
@@ -1110,7 +1108,7 @@ public class BodyAnnotationTest {
@Rest(serializers=JsonSerializer.class,parsers=JsonParser.class)
public static class I {
@RestMethod(name=POST,path="/")
- public DTOs.B g(@Body(r=true) DTOs.B content) throws Exception {
+ public XBeans.XB g(@Body(r=true) XBeans.XB content) throws Exception {
return content;
}
}
@@ -1132,7 +1130,7 @@ public class BodyAnnotationTest {
@RestMethod(name=POST,path="/")
@BeanConfig(applyBean={@Bean(on="A,B,C",sort=true)})
@UrlEncodingConfig(applyUrlEncoding={@UrlEncoding(on="C",expandedParams=true)})
- public DTOs2.B g(@Body(r=true) DTOs2.B content) throws Exception {
+ public XBeans.XE g(@Body(r=true) XBeans.XE content) throws Exception {
return content;
}
}
diff --git a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/FormDataAnnotationTest.java b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/FormDataAnnotationTest.java
index 1513c0c..4bfd282 100644
--- a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/FormDataAnnotationTest.java
+++ b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/FormDataAnnotationTest.java
@@ -27,7 +27,7 @@ import org.apache.juneau.json.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.mock2.*;
-import org.apache.juneau.rest.testutils.*;
+import org.apache.juneau.testutils.pojos.*;
import org.apache.juneau.urlencoding.*;
import org.junit.*;
diff --git a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/HeaderAnnotationTest.java b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/HeaderAnnotationTest.java
index 44c5153..e1e6d10 100644
--- a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/HeaderAnnotationTest.java
+++ b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/HeaderAnnotationTest.java
@@ -25,7 +25,7 @@ import org.apache.juneau.http.annotation.*;
import org.apache.juneau.json.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.mock2.*;
-import org.apache.juneau.rest.testutils.*;
+import org.apache.juneau.testutils.pojos.*;
import org.junit.*;
@FixMethodOrder(NAME_ASCENDING)
diff --git a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/PathAnnotationTest.java b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/PathAnnotationTest.java
index 9b63eea..ce84138 100644
--- a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/PathAnnotationTest.java
+++ b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/PathAnnotationTest.java
@@ -28,7 +28,7 @@ import org.apache.juneau.marshall.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.mock2.*;
-import org.apache.juneau.rest.testutils.*;
+import org.apache.juneau.testutils.pojos.*;
import org.junit.*;
@FixMethodOrder(NAME_ASCENDING)
diff --git a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/PathRemainderAnnotationTest.java b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/PathRemainderAnnotationTest.java
index 99f5468..13aa04e 100644
--- a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/PathRemainderAnnotationTest.java
+++ b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/PathRemainderAnnotationTest.java
@@ -22,7 +22,7 @@ import org.apache.juneau.http.annotation.Path;
import org.apache.juneau.json.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.mock2.*;
-import org.apache.juneau.rest.testutils.*;
+import org.apache.juneau.testutils.pojos.*;
import org.junit.*;
@FixMethodOrder(NAME_ASCENDING)
diff --git a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/QueryAnnotationTest.java b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/QueryAnnotationTest.java
index 8bc7be1..8830cb0 100644
--- a/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/QueryAnnotationTest.java
+++ b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/annotation2/QueryAnnotationTest.java
@@ -28,7 +28,7 @@ import org.apache.juneau.jsonschema.annotation.Items;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.mock2.*;
-import org.apache.juneau.rest.testutils.*;
+import org.apache.juneau.testutils.pojos.*;
import org.junit.*;
@FixMethodOrder(NAME_ASCENDING)
diff --git a/juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/TestUtils.java b/juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/testutils/TestUtils.java
similarity index 100%
rename from juneau-rest/juneau-rest-mock-utest/src/test/java/org/apache/juneau/rest/testutils/TestUtils.java
rename to juneau-rest/juneau-rest-server-utest/src/test/java/org/apache/juneau/rest/testutils/TestUtils.java