This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch jbFixRestNpe
in repository https://gitbox.apache.org/repos/asf/juneau.git

commit 848c9e20563e75908623c9e01e4d570873943e5c
Author: JamesBognar <[email protected]>
AuthorDate: Sat Jul 9 10:07:04 2022 -0400

    Add @Query(def) annotation.
---
 .../apache/juneau/http/annotation/FormData.java    |   7 ++
 .../juneau/http/annotation/FormDataAnnotation.java |  33 ++++++-
 .../org/apache/juneau/http/annotation/Header.java  |   7 ++
 .../juneau/http/annotation/HeaderAnnotation.java   |  33 ++++++-
 .../org/apache/juneau/http/annotation/Path.java    |   7 ++
 .../juneau/http/annotation/PathAnnotation.java     |  33 ++++++-
 .../org/apache/juneau/http/annotation/Query.java   |   7 ++
 .../juneau/http/annotation/QueryAnnotation.java    |  38 +++++--
 .../org/apache/juneau/rest/arg/FormDataArg.java    |   5 +-
 .../java/org/apache/juneau/rest/arg/HeaderArg.java |   5 +-
 .../java/org/apache/juneau/rest/arg/PathArg.java   |   5 +-
 .../java/org/apache/juneau/rest/arg/QueryArg.java  |   8 +-
 .../juneau/rest/httppart/RequestFormParam.java     |  13 +++
 .../apache/juneau/rest/httppart/RequestHeader.java |  14 ++-
 .../juneau/rest/httppart/RequestPathParam.java     |  14 ++-
 .../juneau/rest/httppart/RequestQueryParam.java    |  14 ++-
 .../http/annotation/FormDataAnnotation_Test.java   |   5 +
 .../http/annotation/HeaderAnnotation_Test.java     |   5 +
 .../http/annotation/PathAnnotation_Test.java       |   5 +
 .../http/annotation/QueryAnnotation_Test.java      |   5 +
 .../juneau/rest/annotation/FormData_Test.java      | 108 ++++++++++++++++++++
 .../apache/juneau/rest/annotation/Header_Test.java | 110 +++++++++++++++++++++
 .../apache/juneau/rest/annotation/Query_Test.java  | 103 +++++++++++++++++++
 23 files changed, 560 insertions(+), 24 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormData.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormData.java
index 38171ac22..ddc248e9c 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormData.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormData.java
@@ -122,6 +122,13 @@ import org.apache.juneau.oapi.*;
 @ContextApply(FormDataAnnotation.Applier.class)
 public @interface FormData {
 
+       /**
+        * Default value for this parameter.
+        *
+        * @return The annotation value.
+        */
+       String def() default "";
+
        /**
         * FORM parameter name.
         *
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormDataAnnotation.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormDataAnnotation.java
index 171f5ecc4..90aa0ff37 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormDataAnnotation.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormDataAnnotation.java
@@ -96,6 +96,18 @@ public class FormDataAnnotation {
                return n;
        }
 
+       /**
+        * Finds the default value from the specified list of annotations.
+        *
+        * @param pi The parameter.
+        * @return The last matching default value, or {@link Value#empty()} if 
not found.
+        */
+       public static Value<String> findDef(ParamInfo pi) {
+               Value<String> n = Value.empty();
+               pi.forEachAnnotation(FormData.class, x -> isNotEmpty(x.def()), 
x -> n.set(x.def()));
+               return n;
+       }
+
        
//-----------------------------------------------------------------------------------------------------------------
        // Builder
        
//-----------------------------------------------------------------------------------------------------------------
@@ -112,7 +124,7 @@ public class FormDataAnnotation {
                Class<? extends HttpPartParser> parser = 
HttpPartParser.Void.class;
                Class<? extends HttpPartSerializer> serializer = 
HttpPartSerializer.Void.class;
                Schema schema = SchemaAnnotation.DEFAULT;
-               String name="", value="";
+               String def="", name="", value="";
 
                /**
                 * Constructor.
@@ -130,6 +142,17 @@ public class FormDataAnnotation {
                        return new Impl(this);
                }
 
+               /**
+                * Sets the {@link FormData#def} property on this annotation.
+                *
+                * @param value The new value for this property.
+                * @return This object.
+                */
+               public Builder def(String value) {
+                       this.def = value;
+                       return this;
+               }
+
                /**
                 * Sets the {@link FormData#name} property on this annotation.
                 *
@@ -228,11 +251,12 @@ public class FormDataAnnotation {
 
                private final Class<? extends HttpPartParser> parser;
                private final Class<? extends HttpPartSerializer> serializer;
-               private final String name, value;
+               private final String name, value, def;
                private final Schema schema;
 
                Impl(Builder b) {
                        super(b);
+                       this.def = b.def;
                        this.name = b.name;
                        this.parser = b.parser;
                        this.schema = b.schema;
@@ -241,6 +265,11 @@ public class FormDataAnnotation {
                        postConstruct();
                }
 
+               @Override /* FormData */
+               public String def() {
+                       return def;
+               }
+
                @Override /* FormData */
                public String name() {
                        return name;
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Header.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Header.java
index 5292cc8bb..0057df7d7 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Header.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Header.java
@@ -88,6 +88,13 @@ import org.apache.juneau.oapi.*;
 @ContextApply(HeaderAnnotation.Applier.class)
 public @interface Header {
 
+       /**
+        * Default value for this parameter.
+        *
+        * @return The annotation value.
+        */
+       String def() default "";
+
        /**
         * HTTP header name.
         * <p>
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/HeaderAnnotation.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/HeaderAnnotation.java
index 8d4154542..1358a0d30 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/HeaderAnnotation.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/HeaderAnnotation.java
@@ -97,6 +97,18 @@ public class HeaderAnnotation {
                return n;
        }
 
+       /**
+        * Finds the default value from the specified list of annotations.
+        *
+        * @param pi The parameter.
+        * @return The last matching default value, or {@link Value#empty()} if 
not found.
+        */
+       public static Value<String> findDef(ParamInfo pi) {
+               Value<String> n = Value.empty();
+               pi.forEachAnnotation(Header.class, x -> isNotEmpty(x.def()), x 
-> n.set(x.def()));
+               return n;
+       }
+
        
//-----------------------------------------------------------------------------------------------------------------
        // Builder
        
//-----------------------------------------------------------------------------------------------------------------
@@ -113,7 +125,7 @@ public class HeaderAnnotation {
                Class<? extends HttpPartParser> parser = 
HttpPartParser.Void.class;
                Class<? extends HttpPartSerializer> serializer = 
HttpPartSerializer.Void.class;
                Schema schema = SchemaAnnotation.DEFAULT;
-               String name="", value="";
+               String name="", value="", def="";
 
                /**
                 * Constructor.
@@ -131,6 +143,17 @@ public class HeaderAnnotation {
                        return new Impl(this);
                }
 
+               /**
+                * Sets the {@link Header#def} property on this annotation.
+                *
+                * @param value The new value for this property.
+                * @return This object.
+                */
+               public Builder def(String value) {
+                       this.def = value;
+                       return this;
+               }
+
                /**
                 * Sets the {@link Header#name} property on this annotation.
                 *
@@ -229,11 +252,12 @@ public class HeaderAnnotation {
 
                private final Class<? extends HttpPartParser> parser;
                private final Class<? extends HttpPartSerializer> serializer;
-               private final String name, value;
+               private final String name, value, def;
                private final Schema schema;
 
                Impl(Builder b) {
                        super(b);
+                       this.def = b.def;
                        this.name = b.name;
                        this.parser = b.parser;
                        this.schema = b.schema;
@@ -242,6 +266,11 @@ public class HeaderAnnotation {
                        postConstruct();
                }
 
+               @Override /* Header */
+               public String def() {
+                       return def;
+               }
+
                @Override /* Header */
                public String name() {
                        return name;
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Path.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Path.java
index d78dd307f..e87eed997 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Path.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Path.java
@@ -85,6 +85,13 @@ import org.apache.juneau.oapi.*;
 @ContextApply(PathAnnotation.Applier.class)
 public @interface Path {
 
+       /**
+        * Default value for this parameter.
+        *
+        * @return The annotation value.
+        */
+       String def() default "";
+
        /**
         * URL path variable name.
         *
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathAnnotation.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathAnnotation.java
index 32c92609d..44d06f760 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathAnnotation.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathAnnotation.java
@@ -96,6 +96,18 @@ public class PathAnnotation {
                return n;
        }
 
+       /**
+        * Finds the default value from the specified list of annotations.
+        *
+        * @param pi The parameter.
+        * @return The last matching default value, or {@link Value#empty()} if 
not found.
+        */
+       public static Value<String> findDef(ParamInfo pi) {
+               Value<String> n = Value.empty();
+               pi.forEachAnnotation(Path.class, x -> isNotEmpty(x.def()), x -> 
n.set(x.def()));
+               return n;
+       }
+
        
//-----------------------------------------------------------------------------------------------------------------
        // Builder
        
//-----------------------------------------------------------------------------------------------------------------
@@ -112,7 +124,7 @@ public class PathAnnotation {
                Class<? extends HttpPartParser> parser = 
HttpPartParser.Void.class;
                Class<? extends HttpPartSerializer> serializer = 
HttpPartSerializer.Void.class;
                Schema schema = SchemaAnnotation.DEFAULT;
-               String name="", value="";
+               String name="", value="", def="";
 
                /**
                 * Constructor.
@@ -141,6 +153,17 @@ public class PathAnnotation {
                        return this;
                }
 
+               /**
+                * Sets the {@link Path#name} property on this annotation.
+                *
+                * @param value The new value for this property.
+                * @return This object.
+                */
+               public Builder def(String value) {
+                       this.def = value;
+                       return this;
+               }
+
                /**
                 * Sets the {@link Path#parser} property on this annotation.
                 *
@@ -228,11 +251,12 @@ public class PathAnnotation {
 
                private final Class<? extends HttpPartParser> parser;
                private final Class<? extends HttpPartSerializer> serializer;
-               private final String  name, value;
+               private final String  name, value, def;
                private final Schema schema;
 
                Impl(Builder b) {
                        super(b);
+                       this.def = b.def;
                        this.name = b.name;
                        this.parser = b.parser;
                        this.schema = b.schema;
@@ -246,6 +270,11 @@ public class PathAnnotation {
                        return name;
                }
 
+               @Override /* Path */
+               public String def() {
+                       return def;
+               }
+
                @Override /* Path */
                public Class<? extends HttpPartParser> parser() {
                        return parser;
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Query.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Query.java
index 01bf7fa41..05f1f4dd2 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Query.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Query.java
@@ -96,6 +96,13 @@ import org.apache.juneau.oapi.*;
 @ContextApply(QueryAnnotation.Applier.class)
 public @interface Query {
 
+       /**
+        * Default value for this parameter.
+        *
+        * @return The annotation value.
+        */
+       String def() default "";
+
        /**
         * URL query parameter name.
         *
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/QueryAnnotation.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/QueryAnnotation.java
index f9fa1d108..3959b1972 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/QueryAnnotation.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/QueryAnnotation.java
@@ -81,10 +81,7 @@ public class QueryAnnotation {
        }
 
        /**
-        * Finds the name from the specified lists of annotations.
-        *
-        * <p>
-        * The last matching name found is returned.
+        * Finds the name from the specified list of annotations.
         *
         * @param pi The parameter.
         * @return The last matching name, or {@link Value#empty()} if not 
found.
@@ -96,6 +93,18 @@ public class QueryAnnotation {
                return n;
        }
 
+       /**
+        * Finds the default value from the specified list of annotations.
+        *
+        * @param pi The parameter.
+        * @return The last matching default value, or {@link Value#empty()} if 
not found.
+        */
+       public static Value<String> findDef(ParamInfo pi) {
+               Value<String> n = Value.empty();
+               pi.forEachAnnotation(Query.class, x -> isNotEmpty(x.def()), x 
-> n.set(x.def()));
+               return n;
+       }
+
        
//-----------------------------------------------------------------------------------------------------------------
        // Builder
        
//-----------------------------------------------------------------------------------------------------------------
@@ -112,7 +121,7 @@ public class QueryAnnotation {
                Class<? extends HttpPartParser> parser = 
HttpPartParser.Void.class;
                Class<? extends HttpPartSerializer> serializer = 
HttpPartSerializer.Void.class;
                Schema schema = SchemaAnnotation.DEFAULT;
-               String name="", value="";
+               String name="", value="", def="";
 
                /**
                 * Constructor.
@@ -130,6 +139,17 @@ public class QueryAnnotation {
                        return new Impl(this);
                }
 
+               /**
+                * Sets the {@link Query#def} property on this annotation.
+                *
+                * @param value The new value for this property.
+                * @return This object.
+                */
+               public Builder def(String value) {
+                       this.def = value;
+                       return this;
+               }
+
                /**
                 * Sets the {@link Query#name} property on this annotation.
                 *
@@ -228,7 +248,7 @@ public class QueryAnnotation {
 
                private final Class<? extends HttpPartParser> parser;
                private final Class<? extends HttpPartSerializer> serializer;
-               private final String name, value;
+               private final String name, value, def;
                private final Schema schema;
 
                Impl(Builder b) {
@@ -238,6 +258,7 @@ public class QueryAnnotation {
                        this.schema = b.schema;
                        this.serializer = b.serializer;
                        this.value = b.value;
+                       this.def = b.def;
                        postConstruct();
                }
 
@@ -265,6 +286,11 @@ public class QueryAnnotation {
                public String value() {
                        return value;
                }
+
+               @Override /* Query */
+               public String def() {
+                       return def;
+               }
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/FormDataArg.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/FormDataArg.java
index 20b8f3bd8..29c1655c1 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/FormDataArg.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/FormDataArg.java
@@ -57,7 +57,7 @@ public class FormDataArg implements RestOpArg {
        private final boolean multi;
        private final HttpPartParser partParser;
        private final HttpPartSchema schema;
-       private final String name;
+       private final String name, def;
        private final ClassInfo type;
 
        /**
@@ -81,6 +81,7 @@ public class FormDataArg implements RestOpArg {
         */
        protected FormDataArg(ParamInfo pi, AnnotationWorkList annotations) {
                this.name = findName(pi).orElseThrow(()->new ArgException(pi, 
"@FormData used without name or value"));
+               this.def = findDef(pi).orElse(null);
                this.type = pi.getParameterType();
                this.schema = HttpPartSchema.create(FormData.class, pi);
                Class<? extends HttpPartParser> pp = schema.getParser();
@@ -113,6 +114,6 @@ public class FormDataArg implements RestOpArg {
                        return req.getBeanSession().convertToType(m, cm);
                }
 
-               return 
rh.getLast(name).parser(ps).schema(schema).as(type.innerType()).orElse(null);
+               return 
rh.getLast(name).parser(ps).schema(schema).def(def).as(type.innerType()).orElse(null);
        }
 }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HeaderArg.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HeaderArg.java
index e7d0ad0d1..4a1f211ad 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HeaderArg.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HeaderArg.java
@@ -98,7 +98,7 @@ public class HeaderArg implements RestOpArg {
        private final HttpPartParser partParser;
        private final HttpPartSchema schema;
        private final boolean multi;
-       private final String name;
+       private final String name, def;
        private final ClassInfo type;
 
        /**
@@ -122,6 +122,7 @@ public class HeaderArg implements RestOpArg {
         */
        protected HeaderArg(ParamInfo pi, AnnotationWorkList annotations) {
                this.name = findName(pi).orElseThrow(() -> new ArgException(pi, 
"@Header used without name or value"));
+               this.def = findDef(pi).orElse(null);
                this.type = pi.getParameterType();
                this.schema = HttpPartSchema.create(Header.class, pi);
                Class<? extends HttpPartParser> pp = schema.getParser();
@@ -154,6 +155,6 @@ public class HeaderArg implements RestOpArg {
                        return req.getBeanSession().convertToType(m, cm);
                }
 
-               return 
rh.getLast(name).parser(ps).schema(schema).as(type.innerType()).orElse(null);
+               return 
rh.getLast(name).parser(ps).schema(schema).def(def).as(type.innerType()).orElse(null);
        }
 }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathArg.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathArg.java
index 3433e9ebd..69b80d384 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathArg.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathArg.java
@@ -50,7 +50,7 @@ import org.apache.juneau.rest.util.*;
 public class PathArg implements RestOpArg {
        private final HttpPartParser partParser;
        private final HttpPartSchema schema;
-       private final String name;
+       private final String name, def;
        private final Type type;
 
        /**
@@ -76,6 +76,7 @@ public class PathArg implements RestOpArg {
         */
        protected PathArg(ParamInfo paramInfo, AnnotationWorkList annotations, 
UrlPathMatcher pathMatcher) {
                this.name = getName(paramInfo, pathMatcher);
+               this.def = findDef(paramInfo).orElse(null);
                this.type = paramInfo.getParameterType().innerType();
                this.schema = HttpPartSchema.create(Path.class, paramInfo);
                Class<? extends HttpPartParser> pp = schema.getParser();
@@ -119,6 +120,6 @@ public class PathArg implements RestOpArg {
                        return req.getBeanSession().convertToType(m, type);
                }
                HttpPartParserSession ps = partParser == null ? 
req.getPartParserSession() : partParser.getPartSession();
-               return 
req.getPathParams().get(name).parser(ps).schema(schema).as(type).orElse(null);
+               return 
req.getPathParams().get(name).parser(ps).schema(schema).def(def).as(type).orElse(null);
        }
 }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/QueryArg.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/QueryArg.java
index a8938ed2c..2e143726f 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/QueryArg.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/QueryArg.java
@@ -14,6 +14,7 @@ package org.apache.juneau.rest.arg;
 
 import static org.apache.juneau.internal.CollectionUtils.*;
 import static org.apache.juneau.internal.StringUtils.*;
+import static org.apache.juneau.http.annotation.QueryAnnotation.*;
 
 import java.util.*;
 
@@ -56,7 +57,7 @@ public class QueryArg implements RestOpArg {
        private final boolean multi;
        private final HttpPartParser partParser;
        private final HttpPartSchema schema;
-       private final String name;
+       private final String name, def;
        private final ClassInfo type;
 
        /**
@@ -79,7 +80,8 @@ public class QueryArg implements RestOpArg {
         * @param annotations The annotations to apply to any new part parsers.
         */
        protected QueryArg(ParamInfo pi, AnnotationWorkList annotations) {
-               this.name = QueryAnnotation.findName(pi).orElseThrow(() -> new 
ArgException(pi, "@Query used without name or value"));
+               this.name = findName(pi).orElseThrow(() -> new ArgException(pi, 
"@Query used without name or value"));
+               this.def = findDef(pi).orElse(null);
                this.type = pi.getParameterType();
                this.schema = HttpPartSchema.create(Query.class, pi);
                Class<? extends HttpPartParser> pp = schema.getParser();
@@ -112,6 +114,6 @@ public class QueryArg implements RestOpArg {
                        return req.getBeanSession().convertToType(m, cm);
                }
 
-               return 
rh.getLast(name).parser(ps).schema(schema).as(type.innerType()).orElse(null);
+               return 
rh.getLast(name).parser(ps).schema(schema).def(def).as(type.innerType()).orElse(null);
        }
 }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestFormParam.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestFormParam.java
index 1e8b914ee..b790a71dc 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestFormParam.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestFormParam.java
@@ -135,6 +135,19 @@ public class RequestFormParam extends RequestHttpPart 
implements NameValuePair {
                return value;
        }
 
+
+       /**
+        * Sets a default value for this part.
+        *
+        * @param def The default value.
+        * @return This object.
+        */
+       public RequestFormParam def(String def) {
+               if (getValue() == null)
+                       value = def;
+               return this;
+       }
+
        
//------------------------------------------------------------------------------------------------------------------
        // Assertions
        
//------------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestHeader.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestHeader.java
index 45459778e..ad147958c 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestHeader.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestHeader.java
@@ -95,7 +95,7 @@ import org.apache.juneau.rest.*;
  */
 public class RequestHeader extends RequestHttpPart implements Header {
 
-       private final String value;
+       private String value;
 
        /**
         * Constructor.
@@ -109,6 +109,18 @@ public class RequestHeader extends RequestHttpPart 
implements Header {
                this.value = value;
        }
 
+       /**
+        * Sets a default value for this part.
+        *
+        * @param def The default value.
+        * @return This object.
+        */
+       public RequestHeader def(String def) {
+               if (value == null)
+                       value = def;
+               return this;
+       }
+
        
//------------------------------------------------------------------------------------------------------------------
        // Retrievers
        
//------------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestPathParam.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestPathParam.java
index 838e390a2..74289917c 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestPathParam.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestPathParam.java
@@ -90,7 +90,7 @@ import org.apache.juneau.rest.*;
  */
 public class RequestPathParam extends RequestHttpPart implements NameValuePair 
{
 
-       private final String value;
+       private String value;
 
        /**
         * Constructor.
@@ -104,6 +104,18 @@ public class RequestPathParam extends RequestHttpPart 
implements NameValuePair {
                this.value = value;
        }
 
+       /**
+        * Sets a default value for this part.
+        *
+        * @param def The default value.
+        * @return This object.
+        */
+       public RequestPathParam def(String def) {
+               if (value == null)
+                       value = def;
+               return this;
+       }
+
        
//------------------------------------------------------------------------------------------------------------------
        // Retrievers
        
//------------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestQueryParam.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestQueryParam.java
index b094192d1..5c1b8e09c 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestQueryParam.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/httppart/RequestQueryParam.java
@@ -90,7 +90,7 @@ import org.apache.juneau.rest.*;
  */
 public class RequestQueryParam extends RequestHttpPart implements 
NameValuePair {
 
-       private final String value;
+       private String value;
 
        /**
         * Constructor.
@@ -104,6 +104,18 @@ public class RequestQueryParam extends RequestHttpPart 
implements NameValuePair
                this.value = value;
        }
 
+       /**
+        * Sets a default value for this part.
+        *
+        * @param def The default value.
+        * @return This object.
+        */
+       public RequestQueryParam def(String def) {
+               if (value == null)
+                       value = def;
+               return this;
+       }
+
        
//------------------------------------------------------------------------------------------------------------------
        // Retrievers
        
//------------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/http/annotation/FormDataAnnotation_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/http/annotation/FormDataAnnotation_Test.java
index 8919f36e8..78c9ab788 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/http/annotation/FormDataAnnotation_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/http/annotation/FormDataAnnotation_Test.java
@@ -32,6 +32,7 @@ public class FormDataAnnotation_Test {
        
//------------------------------------------------------------------------------------------------------------------
 
        FormData a1 = FormDataAnnotation.create()
+               .def("def")
                .name("name")
                .on("on")
                .onClass(X1.class)
@@ -41,6 +42,7 @@ public class FormDataAnnotation_Test {
                .build();
 
        FormData a2 = FormDataAnnotation.create()
+               .def("def")
                .name("name")
                .on("on")
                .onClass(X1.class)
@@ -53,6 +55,7 @@ public class FormDataAnnotation_Test {
        public void a01_basic() {
                assertObject(a1).asJson().isMatches(""
                        + "{"
+                               + "def:'def',"
                                + "name:'name',"
                                + "on:['on'],"
                                + 
"onClass:['org.apache.juneau.http.annotation.FormDataAnnotation_Test$X1'],"
@@ -112,6 +115,7 @@ public class FormDataAnnotation_Test {
        
//------------------------------------------------------------------------------------------------------------------
 
        @FormData(
+               def="def",
                name="name",
                on="on",
                onClass=X1.class,
@@ -123,6 +127,7 @@ public class FormDataAnnotation_Test {
        FormData d1 = D1.class.getAnnotationsByType(FormData.class)[0];
 
        @FormData(
+               def="def",
                name="name",
                on="on",
                onClass=X1.class,
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/http/annotation/HeaderAnnotation_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/http/annotation/HeaderAnnotation_Test.java
index 09c779f21..371c436c0 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/http/annotation/HeaderAnnotation_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/http/annotation/HeaderAnnotation_Test.java
@@ -32,6 +32,7 @@ public class HeaderAnnotation_Test {
        
//------------------------------------------------------------------------------------------------------------------
 
        Header a1 = HeaderAnnotation.create()
+               .def("def")
                .name("name")
                .on("on")
                .onClass(X1.class)
@@ -41,6 +42,7 @@ public class HeaderAnnotation_Test {
                .build();
 
        Header a2 = HeaderAnnotation.create()
+               .def("def")
                .name("name")
                .on("on")
                .onClass(X1.class)
@@ -53,6 +55,7 @@ public class HeaderAnnotation_Test {
        public void a01_basic() {
                assertObject(a1).asJson().isMatches(""
                        + "{"
+                               + "def:'def',"
                                + "name:'name',"
                                + "on:['on'],"
                                + "onClass:['"+CNAME+"$X1'],"
@@ -112,6 +115,7 @@ public class HeaderAnnotation_Test {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Header(
+               def="def",
                name="name",
                on="on",
                onClass=X1.class,
@@ -123,6 +127,7 @@ public class HeaderAnnotation_Test {
        Header d1 = D1.class.getAnnotationsByType(Header.class)[0];
 
        @Header(
+               def="def",
                name="name",
                on="on",
                onClass=X1.class,
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/http/annotation/PathAnnotation_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/http/annotation/PathAnnotation_Test.java
index 0f1506f38..797475461 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/http/annotation/PathAnnotation_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/http/annotation/PathAnnotation_Test.java
@@ -32,6 +32,7 @@ public class PathAnnotation_Test {
        
//------------------------------------------------------------------------------------------------------------------
 
        Path a1 = PathAnnotation.create()
+               .def("def")
                .name("name")
                .on("on")
                .onClass(X1.class)
@@ -41,6 +42,7 @@ public class PathAnnotation_Test {
                .build();
 
        Path a2 = PathAnnotation.create()
+               .def("def")
                .name("name")
                .on("on")
                .onClass(X1.class)
@@ -53,6 +55,7 @@ public class PathAnnotation_Test {
        public void a01_basic() {
                assertObject(a1).asJson().isMatches(""
                        + "{"
+                               + "def:'def',"
                                + "name:'name',"
                                + "on:['on'],"
                                + "onClass:['"+CNAME+"$X1'],"
@@ -112,6 +115,7 @@ public class PathAnnotation_Test {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Path(
+               def="def",
                name="name",
                on="on",
                onClass=X1.class,
@@ -123,6 +127,7 @@ public class PathAnnotation_Test {
        Path d1 = D1.class.getAnnotationsByType(Path.class)[0];
 
        @Path(
+               def="def",
                name="name",
                on="on",
                onClass=X1.class,
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/http/annotation/QueryAnnotation_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/http/annotation/QueryAnnotation_Test.java
index 40afced92..7256e7cb4 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/http/annotation/QueryAnnotation_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/http/annotation/QueryAnnotation_Test.java
@@ -32,6 +32,7 @@ public class QueryAnnotation_Test {
        
//------------------------------------------------------------------------------------------------------------------
 
        Query a1 = QueryAnnotation.create()
+               .def("def")
                .name("name")
                .on("on")
                .onClass(X1.class)
@@ -41,6 +42,7 @@ public class QueryAnnotation_Test {
                .build();
 
        Query a2 = QueryAnnotation.create()
+               .def("def")
                .name("name")
                .on("on")
                .onClass(X1.class)
@@ -53,6 +55,7 @@ public class QueryAnnotation_Test {
        public void a01_basic() {
                assertObject(a1).asJson().isMatches(""
                        + "{"
+                               + "def:'def',"
                                + "name:'name',"
                                + "on:['on'],"
                                + "onClass:['"+CNAME+"$X1'],"
@@ -112,6 +115,7 @@ public class QueryAnnotation_Test {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Query(
+               def="def",
                name="name",
                on="on",
                onClass=X1.class,
@@ -123,6 +127,7 @@ public class QueryAnnotation_Test {
        Query d1 = D1.class.getAnnotationsByType(Query.class)[0];
 
        @Query(
+               def="def",
                name="name",
                on="on",
                onClass=X1.class,
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/FormData_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/FormData_Test.java
index 80f614739..d5a572046 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/FormData_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/FormData_Test.java
@@ -211,4 +211,112 @@ public class FormData_Test {
                        .assertCode().is(200)
                        .assertContent().is("null");
        }
+
+       
//------------------------------------------------------------------------------------------------------------------
+       // Default form data parameter.
+       
//------------------------------------------------------------------------------------------------------------------
+
+       @Rest(serializers=SimpleJsonSerializer.class)
+       public static class F {
+               @RestPost
+               public Object a1(@FormData(name="f1",def="1") Integer f1) 
throws Exception {
+                       assertNotNull(f1);
+                       return f1;
+               }
+               @RestPost
+               public Object a2(@FormData(name="f1",def="1") Optional<Integer> 
f1) throws Exception {
+                       assertNotNull(f1);
+                       return f1;
+               }
+               @RestPost
+               public Object b1(@FormData(name="f1",def="a=2,b=bar") ABean f1) 
throws Exception {
+                       assertNotNull(f1);
+                       return f1;
+               }
+               @RestPost
+               public Object b2(@FormData(name="f1",def="a=2,b=bar") 
Optional<ABean> f1) throws Exception {
+                       assertNotNull(f1);
+                       return f1;
+               }
+               @RestPost
+               public Object c1(@FormData(name="f1",def="@((a=2,b=bar))") 
List<ABean> f1) throws Exception {
+                       assertNotNull(f1);
+                       return f1;
+               }
+               @RestPost
+               public Object c2(@FormData(name="f1",def="@((a=2,b=bar))") 
Optional<List<ABean>> f1) throws Exception {
+                       assertNotNull(f1);
+                       return f1;
+               }
+               @RestPost
+               public Object d(@FormData(name="f1",def="@((a=2,b=bar))") 
List<Optional<ABean>> f1) throws Exception {
+                       return f1;
+               }
+       }
+
+       @Test
+       public void f01_defaultParams() throws Exception {
+               RestClient f = 
MockRestClient.create(F.class).accept("application/json").contentType("application/x-www-form-urlencoded").build();
+
+               f.post("/a1", "f1=123")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("123");
+               f.post("/a1", "")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("1");
+               f.post("/a2", "f1=123")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("123");
+               f.post("/a2", "")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("1");
+
+               f.post("/b1", "f1=a=1,b=foo")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("{a:1,b:'foo'}");
+               f.post("/b1", "")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("{a:2,b:'bar'}");
+               f.post("/b2", "f1=a=1,b=foo")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("{a:1,b:'foo'}");
+               f.post("/b2", "")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("{a:2,b:'bar'}");
+
+               f.post("/c1", "f1=@((a=1,b=foo))")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:1,b:'foo'}]");
+               f.post("/c1", "null")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:2,b:'bar'}]");
+               f.post("/c2", "f1=@((a=1,b=foo))")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:1,b:'foo'}]");
+               f.post("/c2", "null")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:2,b:'bar'}]");
+
+
+               f.post("/d", "f1=@((a=1,b=foo))")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:1,b:'foo'}]");
+               f.post("/d", "null")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:2,b:'bar'}]");
+       }
 }
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Header_Test.java 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Header_Test.java
index 9d589f3bb..082f789e6 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Header_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Header_Test.java
@@ -210,4 +210,114 @@ public class Header_Test {
                
e.get("/a").header("H1",7).header("H2",8).header("H3",9).run().assertContent().is("{h1:'7',h2:'8',h3:'9'}");
                
e.get("/a").header("h1",7).header("h2",8).header("h3",9).run().assertContent().is("{h1:'7',h2:'8',h3:'9'}");
        }
+
+       
//------------------------------------------------------------------------------------------------------------------
+       // Default parameters
+       
//------------------------------------------------------------------------------------------------------------------
+
+       @Rest(serializers=SimpleJsonSerializer.class)
+       public static class F {
+               @RestGet
+               public Object a1(@Header(name="f1", def="1") Integer f1) throws 
Exception {
+                       assertNotNull(f1);
+                       return f1;
+               }
+               @RestGet
+               public Object a2(@Header(name="f1", def="1") Optional<Integer> 
f1) throws Exception {
+                       assertNotNull(f1);
+                       return f1.get();
+               }
+               @RestGet
+               public Object b1(@Header(name="f1", def="a=1,b=foo") ABean f1) 
throws Exception {
+                       assertNotNull(f1);
+                       return f1;
+               }
+               @RestGet
+               public Object b2(@Header(name="f1", def="a=1,b=foo") 
Optional<ABean> f1) throws Exception {
+                       assertNotNull(f1);
+                       return f1.get();
+               }
+               @RestGet
+               public Object c1(@Header(name="f1", def="@((a=1,b=foo))") 
List<ABean> f1) throws Exception {
+                       assertNotNull(f1);
+                       return f1;
+               }
+               @RestGet
+               public Object c2(@Header(name="f1", def="@((a=1,b=foo))") 
Optional<List<ABean>> f1) throws Exception {
+                       assertNotNull(f1);
+                       return f1.get();
+               }
+               @RestGet
+               public Object d(@Header(name="f1", def="@((a=1,b=foo))") 
List<Optional<ABean>> f1) throws Exception {
+                       return f1;
+               }
+       }
+
+       @Test
+       public void f01_defaultHeaders() throws Exception {
+               RestClient f = MockRestClient.buildJson(F.class);
+               f.get("/a1")
+                       .header("f1","123")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("123");
+               f.get("/a1")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("1");
+               f.get("/a2")
+                       .header("f1","123")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("123");
+               f.get("/a2")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("1");
+               f.get("/b1")
+                       .header("f1","a=2,b=bar")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("{a:2,b:'bar'}");
+               f.get("/b1")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("{a:1,b:'foo'}");
+               f.get("/b2")
+                       .header("f1","a=2,b=bar")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("{a:2,b:'bar'}");
+               f.get("/b2")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("{a:1,b:'foo'}");
+               f.get("/c1")
+                       .header("f1","@((a=2,b=bar))")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:2,b:'bar'}]");
+               f.get("/c1")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:1,b:'foo'}]");
+               f.get("/c2")
+                       .header("f1","@((a=2,b=bar))")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:2,b:'bar'}]");
+               f.get("/c2")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:1,b:'foo'}]");
+               f.get("/d")
+                       .header("f1","@((a=2,b=bar))")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:2,b:'bar'}]");
+               f.get("/d")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:1,b:'foo'}]");
+       }
 }
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Query_Test.java 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Query_Test.java
index 82b5b9df6..170332cc2 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Query_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Query_Test.java
@@ -288,4 +288,107 @@ public class Query_Test {
                        .assertCode().is(200)
                        .assertContent().is("null");
        }
+
+       
//------------------------------------------------------------------------------------------------------------------
+       // Default parameters
+       
//------------------------------------------------------------------------------------------------------------------
+
+       @Rest(serializers=SimpleJsonSerializer.class)
+       public static class F {
+               @RestGet
+               public Object a1(@Query(name="f1", def="1") Integer f1) throws 
Exception {
+                       assertNotNull(f1);
+                       return f1;
+               }
+               @RestGet
+               public Object a2(@Query(name="f1", def="1") Optional<Integer> 
f1) throws Exception {
+                       assertNotNull(f1);
+                       return f1.get();
+               }
+               @RestGet
+               public Object b1(@Query(name="f1", def="a=1,b=foo") ABean f1) 
throws Exception {
+                       assertNotNull(f1);
+                       return f1;
+               }
+               @RestGet
+               public Object b2(@Query(name="f1", def="a=1,b=foo") 
Optional<ABean> f1) throws Exception {
+                       assertNotNull(f1);
+                       return f1.get();
+               }
+               @RestGet
+               public Object c1(@Query(name="f1", def="@((a=1,b=foo))") 
List<ABean> f1) throws Exception {
+                       assertNotNull(f1);
+                       return f1;
+               }
+               @RestGet
+               public Object c2(@Query(name="f1", def="@((a=1,b=foo))") 
Optional<List<ABean>> f1) throws Exception {
+                       assertNotNull(f1);
+                       return f1.get();
+               }
+               @RestGet
+               public Object d(@Query(name="f1", def="@((a=1,b=foo))") 
List<Optional<ABean>> f1) throws Exception {
+                       return f1;
+               }
+       }
+
+       @Test
+       public void f01_defaultParams() throws Exception {
+               RestClient f = MockRestClient.buildJson(F.class);
+               f.get("/a1?f1=123")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("123");
+               f.get("/a1")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("1");
+               f.get("/a2?f1=123")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("123");
+               f.get("/a2")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("1");
+               f.get("/b1?f1=a=2,b=bar")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("{a:2,b:'bar'}");
+               f.get("/b1")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("{a:1,b:'foo'}");
+               f.get("/b2?f1=a=2,b=bar")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("{a:2,b:'bar'}");
+               f.get("/b2")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("{a:1,b:'foo'}");
+               f.get("/c1?f1=@((a=2,b=bar))")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:2,b:'bar'}]");
+               f.get("/c1")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:1,b:'foo'}]");
+               f.get("/c2?f1=@((a=2,b=bar))")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:2,b:'bar'}]");
+               f.get("/c2")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:1,b:'foo'}]");
+               f.get("/d?f1=@((a=2,b=bar))")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:2,b:'bar'}]");
+               f.get("/d")
+                       .run()
+                       .assertCode().is(200)
+                       .assertContent().is("[{a:1,b:'foo'}]");
+       }
 }

Reply via email to