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 4316a93  REST refactoring.
4316a93 is described below

commit 4316a935bf7ed327dd031b3fbc5d8e335b1f9971
Author: JamesBognar <[email protected]>
AuthorDate: Sun Feb 21 17:37:26 2021 -0500

    REST refactoring.
---
 .../java/org/apache/juneau/BeanSessionArgs.java    |   4 +-
 .../main/java/org/apache/juneau/SessionArgs.java   |   2 +-
 .../java/org/apache/juneau/SessionProperties.java  |   6 +-
 .../apache/juneau/http/BasicNamedAttribute.java    |  40 ++-
 .../apache/juneau/parser/ParserSessionArgs.java    |   2 +-
 .../juneau/serializer/SerializerSessionArgs.java   |   2 +-
 .../org/apache/juneau/rest/RequestAttribute.java   |  74 ++++++
 .../org/apache/juneau/rest/RequestAttributes.java  | 279 +++++++++++----------
 .../java/org/apache/juneau/rest/RequestBody.java   |   2 +-
 .../org/apache/juneau/rest/RequestFormParams.java  |  22 +-
 .../org/apache/juneau/rest/RequestHeaders.java     |  30 ++-
 .../org/apache/juneau/rest/RequestPathParams.java  |  28 ++-
 .../org/apache/juneau/rest/RequestQueryParams.java |  21 +-
 .../apache/juneau/rest/RestOperationContext.java   |   2 +-
 .../java/org/apache/juneau/rest/RestRequest.java   |   9 +-
 .../org/apache/juneau/rest/args/AttributeArg.java  |  10 +-
 .../juneau/rest/reshandlers/DefaultHandler.java    |   2 +-
 .../org/apache/juneau/rest/util/UrlPathMatch.java  |   4 +-
 .../juneau/rest/vars/RequestAttributeVar.java      |   4 +-
 .../org/apache/juneau/rest/vars/RequestVar.java    |   2 +-
 .../juneau/rest/vars/SerializedRequestAttrVar.java |   4 +-
 .../apache/juneau/rest/widget/MenuItemWidget.java  |   4 +-
 .../juneau/rest/annotation/RestHook_Test.java      |  22 +-
 .../juneau/rest/annotation/Rest_RVars_Test.java    |   2 +-
 .../rest/annotation/Restx_ReqAttrs_Test.java       |  52 ++--
 25 files changed, 410 insertions(+), 219 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSessionArgs.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSessionArgs.java
index cacf2c2..7fded29 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSessionArgs.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSessionArgs.java
@@ -87,7 +87,7 @@ public class BeanSessionArgs extends SessionArgs {
        }
 
        @Override /* GENERATED - SessionArgs */
-       public BeanSessionArgs properties(OMap value) {
+       public BeanSessionArgs properties(Map<String,Object> value) {
                super.properties(value);
                return this;
        }
@@ -110,7 +110,7 @@ public class BeanSessionArgs extends SessionArgs {
        public OMap toMap() {
                return super.toMap()
                        .a(
-                               "BeanSessionArgs", 
+                               "BeanSessionArgs",
                                OMap
                                        .create()
                                        .filtered()
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/SessionArgs.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/SessionArgs.java
index ed60c1c..20e88a0 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/SessionArgs.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/SessionArgs.java
@@ -132,7 +132,7 @@ public class SessionArgs {
         * @return This object (for method chaining).
         */
        @FluentSetter
-       public SessionArgs properties(OMap value) {
+       public SessionArgs properties(Map<String,Object> value) {
                this.properties = SessionProperties.create(value);
                return this;
        }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/SessionProperties.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/SessionProperties.java
index d4bc6c3..921758d 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/SessionProperties.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/SessionProperties.java
@@ -42,15 +42,15 @@ public class SessionProperties {
         * @param inner The initial contents of these properties.
         * @return A new instance of this class.
         */
-       public static SessionProperties create(OMap inner) {
+       public static SessionProperties create(Map<String,Object> inner) {
                return new SessionProperties(inner);
        }
 
        /**
         * Constructor.
         */
-       private SessionProperties(OMap inner) {
-               this.map = inner == null ? new OMap() : inner;
+       private SessionProperties(Map<String,Object> inner) {
+               this.map = inner == null ? new OMap() : inner instanceof OMap ? 
(OMap)inner : new OMap(inner);
        }
 
        /**
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicNamedAttribute.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicNamedAttribute.java
index 038c4c3..60e9f3b 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicNamedAttribute.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicNamedAttribute.java
@@ -14,6 +14,7 @@ package org.apache.juneau.http;
 
 import static org.apache.juneau.internal.StringUtils.*;
 
+import java.util.*;
 import java.util.function.*;
 
 import org.apache.http.*;
@@ -107,9 +108,46 @@ public class BasicNamedAttribute implements NamedAttribute 
{
                return unwrap(value);
        }
 
+       /**
+        * Returns <jk>true</jk> if the value exists.
+        *
+        * <p>
+        * This is a shortcut for calling <c>asString().isPresent()</c>.
+        *
+        * @return <jk>true</jk> if the value exists.
+        */
+       public boolean isPresent() {
+               return getValue() != null;
+       }
+
+       /**
+        * If a value is present, returns the value, otherwise throws {@link 
NoSuchElementException}.
+        *
+        * <p>
+        * This is a shortcut for calling <c>asString().get()</c>.
+        *
+        * @return The value if present.
+        */
+       public Object get() {
+               return Optional.ofNullable(getValue()).get();
+       }
+
+       /**
+        * If a value is present, returns the value, otherwise returns other.
+        *
+        * <p>
+        * This is a shortcut for calling 
<c>asString().orElse(<jv>other</jv>)</c>.
+        *
+        * @param other The other value.
+        * @return The value if present or the other value if not.
+        */
+       public Object orElse(Object other) {
+               return Optional.ofNullable(getValue()).orElse(other);
+       }
+
        @Override /* Object */
        public String toString() {
-               return urlEncode(getName()) + "=" + urlEncode(getValue());
+               return urlEncode(getName()) + "=" + getValue();
        }
 
        private Object unwrap(Object o) {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSessionArgs.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSessionArgs.java
index 79d1e23..b0741a1 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSessionArgs.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSessionArgs.java
@@ -143,7 +143,7 @@ public final class ParserSessionArgs extends 
BeanSessionArgs {
        }
 
        @Override /* GENERATED - SessionArgs */
-       public ParserSessionArgs properties(OMap value) {
+       public ParserSessionArgs properties(Map<String,Object> value) {
                super.properties(value);
                return this;
        }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSessionArgs.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSessionArgs.java
index 8690729..324dd33 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSessionArgs.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSessionArgs.java
@@ -189,7 +189,7 @@ public final class SerializerSessionArgs extends 
BeanSessionArgs {
        }
 
        @Override /* GENERATED - SessionArgs */
-       public SerializerSessionArgs properties(OMap value) {
+       public SerializerSessionArgs properties(Map<String,Object> value) {
                super.properties(value);
                return this;
        }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestAttribute.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestAttribute.java
new file mode 100644
index 0000000..fe577e1
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestAttribute.java
@@ -0,0 +1,74 @@
+// 
***************************************************************************************************************************
+// * 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;
+
+import static java.util.Optional.*;
+import static org.apache.juneau.internal.StringUtils.*;
+
+import java.util.*;
+
+import org.apache.juneau.http.*;
+import org.apache.juneau.http.exception.HttpException;
+
+/**
+ * Represents a single request attribute on an HTTP request.
+ */
+public class RequestAttribute extends BasicNamedAttribute {
+
+       private final RestRequest req;
+
+       /**
+        * Constructor.
+        *
+        * @param request The request object.
+        * @param name The parameter name.
+        * @param value The parameter value.
+        */
+       public RequestAttribute(RestRequest request, String name, Object value) 
{
+               super(name, value);
+               this.req = request;
+       }
+
+       
//------------------------------------------------------------------------------------------------------------------
+       // Retrievers
+       
//------------------------------------------------------------------------------------------------------------------
+
+       /**
+        * Returns the value of this part as a string.
+        *
+        * @return The value of this part as a string, or {@link 
Optional#empty()} if the part was not present.
+        */
+       public Optional<String> asString() {
+               return ofNullable(stringify(getValue()));
+       }
+
+       /**
+        * Converts this part to the specified POJO.
+        *
+        * @param <T> The type to convert to.
+        * @param type The type to convert to.
+        * @return The converted type, or {@link Optional#empty()} if the part 
is not present.
+        * @throws HttpException If value could not be parsed.
+        */
+       public <T> Optional<T> asType(Class<T> type) {
+               return 
ofNullable(req.getBeanSession().convertToType(getValue(), type));
+       }
+
+       
//------------------------------------------------------------------------------------------------------------------
+       // Header passthrough methods.
+       
//------------------------------------------------------------------------------------------------------------------
+
+       // <FluentSetters>
+
+       // </FluentSetters>
+}
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestAttributes.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestAttributes.java
index 59bd365..ada8132 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestAttributes.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestAttributes.java
@@ -12,7 +12,7 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.rest;
 
-import static org.apache.juneau.internal.CollectionUtils.*;
+import static org.apache.juneau.assertions.Assertions.*;
 
 import java.util.*;
 
@@ -20,7 +20,6 @@ import javax.servlet.http.*;
 
 import org.apache.juneau.collections.*;
 import org.apache.juneau.http.*;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.svl.*;
 
 /**
@@ -33,162 +32,172 @@ import org.apache.juneau.svl.*;
  *     <li class='link'>{@doc RestmRequestAttributes}
  * </ul>
  */
-public class RequestAttributes extends OMap {
+public class RequestAttributes {
 
-       private static final long serialVersionUID = 1L;
-
-       final HttpServletRequest req;
-       final OMap defaultEntries;
+       final RestRequest req;
+       final HttpServletRequest sreq;
        final VarResolverSession vs;
 
        RequestAttributes(RestRequest req) {
                super();
-               this.req = req.getHttpServletRequest();
-               this.defaultEntries = new OMap();
+               this.req = req;
+               this.sreq = req.getHttpServletRequest();
                this.vs = req.getVarResolverSession();
        }
 
        /**
-        * Adds values to these attributes if they're not already set.
+        * Adds default entries to the request attributes.
         *
-        * @param pairs The attributes to add.
+        * @param pairs
+        *      The default entries.
+        *      <br>Can be <jk>null</jk>.
         * @return This object (for method chaining).
         */
        public RequestAttributes addDefault(List<NamedAttribute> pairs) {
-               for (NamedAttribute p : pairs) {
-                       String key = p.getName();
-                       Object value = p.getValue();
-                       Object v = get(key);
-                       if (v == null || StringUtils.isEmpty(v.toString()))
-                               put(key, value);
+               for (NamedAttribute p : pairs)
+                       if (sreq.getAttribute(p.getName()) == null) {
+                               Object o = p.getValue();
+                               sreq.setAttribute(p.getName(), o instanceof 
String ? vs.resolve(o) : o);
+                       }
+               return this;
+       }
+
+       /**
+        * Adds default entries to the request attributes.
+        *
+        * @param pairs
+        *      The default entries.
+        *      <br>Can be <jk>null</jk>.
+        * @return This object (for method chaining).
+        */
+       public RequestAttributes addDefault(NamedAttribute...pairs) {
+               return addDefault(Arrays.asList(pairs));
+       }
+
+       /**
+        * Returns the request attribute with the specified name.
+        *
+        * @param name The attribute name.
+        * @return The parameter value, or {@link Optional#empty()} if it 
doesn't exist.
+        */
+       public RequestAttribute get(String name) {
+               return new RequestAttribute(req, name, sreq.getAttribute(name));
+       }
+
+       /**
+        * Returns all the attribute on this request.
+        *
+        * @return All the attribute on this request.
+        */
+       public List<RequestAttribute> getAll() {
+               ArrayList<RequestAttribute> l = new ArrayList<>();
+               Enumeration<String> e = sreq.getAttributeNames();
+               while (e.hasMoreElements()) {
+                       String n = e.nextElement();
+                       l.add(new RequestAttribute(req, n, 
sreq.getAttribute(n)));
                }
+               return l;
+       }
+
+       /**
+        * Returns <jk>true</jk> if the attributes with the specified names are 
present.
+        *
+        * @param names The attribute names.  Must not be <jk>null</jk>.
+        * @return <jk>true</jk> if the parameters with the specified names are 
present.
+        */
+       public boolean contains(String...names) {
+               assertArgNotNull("names", names);
+               for (String n : names)
+                       if (sreq.getAttribute(n) == null)
+                               return false;
+               return true;
+       }
+
+       /**
+        * Returns <jk>true</jk> if the attribute with any of the specified 
names are present.
+        *
+        * @param names The attribute names.  Must not be <jk>null</jk>.
+        * @return <jk>true</jk> if the attribute with any of the specified 
names are present.
+        */
+       public boolean containsAny(String...names) {
+               assertArgNotNull("names", names);
+               for (String n : names)
+                       if (sreq.getAttribute(n) != null)
+                               return true;
+               return false;
+       }
+
+       /**
+        * Sets a request attribute.
+        *
+        * @param name The attribute name.  Must not be <jk>null</jk>.
+        * @param value
+        *      The attribute value.
+        *      <br>Can be <jk>null</jk>.
+        * @return This object (for method chaining).
+        */
+       public RequestAttributes set(String name, Object value) {
+               assertArgNotNull("name", name);
+               sreq.setAttribute(name, value);
                return this;
        }
 
-       @Override /* Map */
-       public Object get(Object key) {
-               if (key == null)
-                       return null;
-               String k = key.toString();
-               Object o = req.getAttribute(k);
-               if (o == null)
-                        o = req.getSession().getAttribute(k);
-               if (o == null)
-                       o = defaultEntries.get(k);
-               return resolve(o);
+       /**
+        * Sets request attributes.
+        *
+        * @param attributes The parameters to set.  Must not be <jk>null</jk> 
or contain <jk>null</jk>.
+        * @return This object (for method chaining).
+        */
+       public RequestAttributes set(NamedAttribute...attributes) {
+               assertArgNotNull("attributes", attributes);
+               for (NamedAttribute p : attributes)
+                       set(p);
+               return this;
        }
 
-       @Override /* Map */
-       public Object put(String key, Object value) {
-               Object o = req.getAttribute(key);
-               req.setAttribute(key, value);
-               return o;
+       /**
+        * Remove request attributes.
+        *
+        * @param name The attribute names.  Must not be <jk>null</jk>.
+        * @return This object (for method chaining).
+        */
+       public RequestAttributes remove(String...name) {
+               assertArgNotNull("name", name);
+               for (String n : name) {
+                       sreq.removeAttribute(n);
+               }
+               return this;
        }
 
-       Object resolve(Object o) {
-               if (o instanceof CharSequence)
-                       o = vs.resolve(o.toString());
-               return o;
+       /**
+        * Remove request attributes.
+        *
+        * @param attributes The attributes to remove.  Must not be 
<jk>null</jk>.
+        * @return This object (for method chaining).
+        */
+       public RequestAttributes remove(NamedAttribute...attributes) {
+               for (NamedAttribute p : attributes)
+                       remove(p.getName());
+               return this;
        }
 
-       @Override /* Map */
-       public Set<java.util.Map.Entry<String,Object>> entrySet() {
-               return new AbstractSet<java.util.Map.Entry<String,Object>>() {
-
-                       @Override /* Set */
-                       public Iterator<java.util.Map.Entry<String,Object>> 
iterator() {
-
-                               return new 
Iterator<java.util.Map.Entry<String,Object>>() {
-                                       Set<String> keys = new 
LinkedHashSet<>();
-                                       {
-                                               for (String s : 
iterable(req.getAttributeNames()))
-                                                       keys.add(s);
-                                               for (String s : 
iterable(req.getSession().getAttributeNames()))
-                                                       keys.add(s);
-                                       }
-                                       Iterator<String> keyIterator = 
keys.iterator();
-                                       Iterator<Map.Entry<String,Object>> 
defaultsIterator = defaultEntries.entrySet().iterator();
-                                       Map.Entry<String,Object> peekNext;
-
-                                       @Override /* Iterator */
-                                       public boolean hasNext() {
-                                               if (keyIterator.hasNext())
-                                                       return true;
-                                               while 
(defaultsIterator.hasNext() && peekNext == null) {
-                                                       peekNext = 
defaultsIterator.next();
-                                                       if 
(keys.contains(peekNext.getKey()))
-                                                               peekNext = null;
-                                               }
-                                               return peekNext != null;
-                                       }
-
-                                       @Override /* Iterator */
-                                       public 
java.util.Map.Entry<String,Object> next() {
-                                               if (keyIterator.hasNext()) {
-                                                       final String k = 
keyIterator.next();
-                                                       return new 
java.util.Map.Entry<String,Object>() {
-
-                                                               @Override /* 
Map.Entry */
-                                                               public String 
getKey() {
-                                                                       return 
k;
-                                                               }
-
-                                                               @Override /* 
Map.Entry */
-                                                               public Object 
getValue() {
-                                                                       return 
resolve(req.getAttribute(k));
-                                                               }
-
-                                                               @Override /* 
Map.Entry */
-                                                               public Object 
setValue(Object value) {
-                                                                       Object 
o = req.getAttribute(k);
-                                                                       
req.setAttribute(k, value);
-                                                                       return 
o;
-                                                               }
-                                                       };
-                                               }
-                                               while 
(defaultsIterator.hasNext() && peekNext == null) {
-                                                       peekNext = 
defaultsIterator.next();
-                                                       if 
(keys.contains(peekNext.getKey()))
-                                                               peekNext = null;
-                                               }
-                                               if (peekNext != null) {
-                                                       final 
java.util.Map.Entry<String,Object> o = peekNext;
-                                                       
java.util.Map.Entry<String,Object> o2 = new 
java.util.Map.Entry<String,Object>() {
-
-                                                               @Override /* 
Map.Entry */
-                                                               public String 
getKey() {
-                                                                       return 
o.getKey();
-                                                               }
-
-                                                               @Override /* 
Map.Entry */
-                                                               public Object 
getValue() {
-                                                                       return 
resolve(o.getValue());
-                                                               }
-
-                                                               @Override /* 
Map.Entry */
-                                                               public Object 
setValue(Object value) {
-                                                                       Object 
o3 = o.getValue();
-                                                                       
req.setAttribute(o.getKey(), value);
-                                                                       return 
resolve(o3);
-                                                               }
-                                                       };
-                                                       peekNext = null;
-                                                       return o2;
-                                               }
-                                               return null;
-                                       }
-
-                               };
-                       }
+       /**
+        * Returns the request attributes as a map.
+        *
+        * @return The request attributes as a map.  Never <jk>null</jk>.
+        */
+       public Map<String,Object> asMap() {
+               OMap m = new OMap();
+               Enumeration<String> e = sreq.getAttributeNames();
+               while (e.hasMoreElements()) {
+                       String n = e.nextElement();
+                       m.put(n, sreq.getAttribute(n));
+               }
+               return m;
+       }
 
-                       @Override /* Set */
-                       public int size() {
-                               int i = defaultEntries.size();
-                               for (String s : 
iterable(req.getAttributeNames()))
-                                       if (! defaultEntries.containsKey(s))
-                                               i++;
-                               return i;
-                       }
-               };
+       @Override /* Object */
+       public String toString() {
+               return asMap().toString();
        }
 }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestBody.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestBody.java
index f83cf30..06854cb 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestBody.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestBody.java
@@ -447,7 +447,7 @@ public class RequestBody {
                        MediaType mediaType = pm.getMediaType();
                        ParserSessionArgs pArgs = ParserSessionArgs
                                .create()
-                               .properties(req.getAttributes())
+                               .properties(req.getAttributes().asMap())
                                .javaMethod(req.getOpContext().getJavaMethod())
                                .locale(locale)
                                .timeZone(timeZone.orElse(null))
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestFormParams.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestFormParams.java
index f8ada01..1a1c5e4 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestFormParams.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestFormParams.java
@@ -26,6 +26,7 @@ import org.apache.juneau.collections.*;
 import org.apache.juneau.httppart.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.rest.util.*;
+import org.apache.juneau.svl.*;
 import org.apache.juneau.utils.*;
 
 /**
@@ -36,6 +37,7 @@ public class RequestFormParams {
        private final RestRequest req;
        private final boolean caseSensitive;
        private HttpPartParserSession parser;
+       private final VarResolverSession vs ;
 
        private List<RequestFormParam> list = new LinkedList<>();
        private Map<String,List<RequestFormParam>> map = new TreeMap<>();
@@ -43,6 +45,7 @@ public class RequestFormParams {
        RequestFormParams(RestRequest req, boolean caseSensitive) throws 
Exception {
                this.req = req;
                this.caseSensitive = caseSensitive;
+               this.vs = req.getVarResolverSession();
 
                Map<String,String[]> m = null;
                Collection<Part> c = null;
@@ -94,6 +97,7 @@ public class RequestFormParams {
                parser = copyFrom.parser;
                list.addAll(copyFrom.list);
                map.putAll(copyFrom.map);
+               vs = copyFrom.vs;
        }
 
        RequestFormParams parser(HttpPartParserSession parser) {
@@ -127,13 +131,29 @@ public class RequestFormParams {
                        if (l == null || hasAllBlanks) {
                                if (hasAllBlanks)
                                        list.removeAll(l);
-                               RequestFormParam x = new RequestFormParam(req, 
name, p.getValue());
+                               RequestFormParam x = new RequestFormParam(req, 
name, vs.resolve(p.getValue()));
                                list.add(x);
                                map.put(key, AList.of(x));
                        }
                }
                return this;
        }
+
+       /**
+        * Adds default entries to these parameters.
+        *
+        * <p>
+        * Similar to {@link #set(String, Object)} but doesn't override 
existing values.
+        *
+        * @param pairs
+        *      The default entries.
+        *      <br>Can be <jk>null</jk>.
+        * @return This object (for method chaining).
+        */
+       public RequestFormParams addDefault(NameValuePair...pairs) {
+               return addDefault(Arrays.asList(pairs));
+       }
+
        /**
         * Returns all the parameters with the specified name.
         *
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestHeaders.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestHeaders.java
index 66bee4e..a2899ce 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestHeaders.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestHeaders.java
@@ -24,6 +24,7 @@ import java.util.function.*;
 import org.apache.http.*;
 import org.apache.juneau.httppart.*;
 import org.apache.juneau.internal.*;
+import org.apache.juneau.svl.*;
 import org.apache.juneau.collections.*;
 
 /**
@@ -40,6 +41,7 @@ public class RequestHeaders {
 
        private final RestRequest req;
        private final boolean caseSensitive;
+       private final VarResolverSession vs ;
 
        private HttpPartParserSession parser;
 
@@ -49,6 +51,7 @@ public class RequestHeaders {
        RequestHeaders(RestRequest req, RequestQueryParams query, boolean 
caseSensitive) {
                this.req = req;
                this.caseSensitive = caseSensitive;
+               this.vs = req.getVarResolverSession();
 
                for (Enumeration<String> e = 
req.getHttpServletRequest().getHeaderNames(); e.hasMoreElements();) {
                        String name = e.nextElement();
@@ -87,17 +90,19 @@ public class RequestHeaders {
                parser = copyFrom.parser;
                list.addAll(copyFrom.list);
                map.putAll(copyFrom.map);
+               vs = copyFrom.vs;
        }
 
        /**
         * Subset constructor.
         */
-       private RequestHeaders(RestRequest req, Map<String,List<RequestHeader>> 
headerMap, HttpPartParserSession parser, boolean caseSensitive) {
-               this.req = req;
+       private RequestHeaders(RequestHeaders copyFrom, 
Map<String,List<RequestHeader>> headerMap) {
+               this.req = copyFrom.req;
                map.putAll(headerMap);
                list = 
headerMap.values().stream().flatMap(List::stream).collect(toList());
-               this.parser = parser;
-               this.caseSensitive = caseSensitive;
+               parser = copyFrom.parser;
+               caseSensitive = copyFrom.caseSensitive;
+               vs = copyFrom.vs;
        }
 
        RequestHeaders parser(HttpPartParserSession parser) {
@@ -130,7 +135,7 @@ public class RequestHeaders {
                        if (l == null || hasAllBlanks) {
                                if (hasAllBlanks)
                                        list.removeAll(l);
-                               RequestHeader x = new RequestHeader(req, name, 
p.getValue());
+                               RequestHeader x = new RequestHeader(req, name, 
vs.resolve(p.getValue()));
                                list.add(x);
                                map.put(key, AList.of(x));
                        }
@@ -139,6 +144,19 @@ public class RequestHeaders {
        }
 
        /**
+        * Adds default entries to these headers.
+        *
+        * <p>
+        * Similar to {@link #set(String, Object)} but doesn't override 
existing values.
+        *
+        * @param pairs The default entries.  Must not be <jk>null</jk>.
+        * @return This object (for method chaining).
+        */
+       public RequestHeaders addDefault(Header...pairs) {
+               return addDefault(Arrays.asList(pairs));
+       }
+
+       /**
         * Returns all the headers with the specified name.
         *
         * @param name The header name.  Must not be <jk>null</jk>.
@@ -324,7 +342,7 @@ public class RequestHeaders {
                        .filter(map::containsKey)
                        .collect(toMap(Function.identity(),map::get));
 
-               return new RequestHeaders(req, m, parser, caseSensitive);
+               return new RequestHeaders(this, m);
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestPathParams.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestPathParams.java
index 9811e77..a270aa8 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestPathParams.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestPathParams.java
@@ -23,6 +23,7 @@ import org.apache.http.*;
 import org.apache.juneau.httppart.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.rest.util.*;
+import org.apache.juneau.svl.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.collections.*;
 
@@ -36,6 +37,7 @@ public class RequestPathParams {
        private final RestRequest req;
        private final boolean caseSensitive;
        private HttpPartParserSession parser;
+       private final VarResolverSession vs;
 
        private List<RequestPathParam> list = new LinkedList<>();
        private Map<String,List<RequestPathParam>> map = new TreeMap<>();
@@ -44,13 +46,13 @@ public class RequestPathParams {
                this.call = call;
                this.req = req;
                this.caseSensitive = caseSensitive;
+               this.vs = req.getVarResolverSession();
 
                // Add parameters from parent context if any.
                @SuppressWarnings("unchecked")
-               Map<String,String> parentVars = 
(Map<String,String>)req.getAttribute("juneau.pathVars").orElse(null);
-               if (parentVars != null)
-                       for (Map.Entry<String,String> e : parentVars.entrySet())
-                               add(e.getKey(), e.getValue());
+               Map<String,String> parentVars = 
(Map<String,String>)req.getAttribute("juneau.pathVars").orElse(Collections.emptyMap());
+               for (Map.Entry<String,String> e : parentVars.entrySet())
+                       add(e.getKey(), e.getValue());
 
                UrlPathMatch pm = call.getUrlPathMatch();
                if (pm != null) {
@@ -74,6 +76,7 @@ public class RequestPathParams {
                parser = copyFrom.parser;
                list.addAll(copyFrom.list);
                map.putAll(copyFrom.map);
+               vs = copyFrom.vs;
        }
 
        RequestPathParams parser(HttpPartParserSession parser) {
@@ -107,7 +110,7 @@ public class RequestPathParams {
                        if (l == null || hasAllBlanks) {
                                if (hasAllBlanks)
                                        list.removeAll(l);
-                               RequestPathParam x = new RequestPathParam(req, 
name, p.getValue());
+                               RequestPathParam x = new RequestPathParam(req, 
name, vs.resolve(p.getValue()));
                                list.add(x);
                                map.put(key, AList.of(x));
                        }
@@ -116,6 +119,21 @@ public class RequestPathParams {
        }
 
        /**
+        * Adds default entries to these parameters.
+        *
+        * <p>
+        * Similar to {@link #set(String, Object)} but doesn't override 
existing values.
+        *
+        * @param pairs
+        *      The default entries.
+        *      <br>Can be <jk>null</jk>.
+        * @return This object (for method chaining).
+        */
+       public RequestPathParams addDefault(NameValuePair...pairs) {
+               return addDefault(Arrays.asList(pairs));
+       }
+
+       /**
         * Returns all the parameters with the specified name.
         *
         * @param name The parameter name.
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestQueryParams.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestQueryParams.java
index 5b88159..69ce044 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestQueryParams.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestQueryParams.java
@@ -22,6 +22,7 @@ import java.util.*;
 import org.apache.http.*;
 import org.apache.juneau.httppart.*;
 import org.apache.juneau.internal.*;
+import org.apache.juneau.svl.*;
 import org.apache.juneau.utils.*;
 import org.apache.juneau.collections.*;
 
@@ -39,6 +40,7 @@ public class RequestQueryParams {
 
        private final RestRequest req;
        private final boolean caseSensitive;
+       private final VarResolverSession vs;
        private HttpPartParserSession parser;
 
        private List<RequestQueryParam> list = new LinkedList<>();
@@ -47,6 +49,7 @@ public class RequestQueryParams {
        RequestQueryParams(RestRequest req, Map<String,String[]> query, boolean 
caseSensitive) {
                this.req = req;
                this.caseSensitive = caseSensitive;
+               this.vs = req.getVarResolverSession();
 
                for (Map.Entry<String,String[]> e : query.entrySet()) {
                        String name = e.getKey();
@@ -81,6 +84,7 @@ public class RequestQueryParams {
                parser = copyFrom.parser;
                list.addAll(copyFrom.list);
                map.putAll(copyFrom.map);
+               vs = copyFrom.vs;
        }
 
        RequestQueryParams parser(HttpPartParserSession parser) {
@@ -114,7 +118,7 @@ public class RequestQueryParams {
                        if (l == null || hasAllBlanks) {
                                if (hasAllBlanks)
                                        list.removeAll(l);
-                               RequestQueryParam x = new 
RequestQueryParam(req, name, p.getValue());
+                               RequestQueryParam x = new 
RequestQueryParam(req, name, vs.resolve(p.getValue()));
                                list.add(x);
                                map.put(key, AList.of(x));
                        }
@@ -123,6 +127,21 @@ public class RequestQueryParams {
        }
 
        /**
+        * Adds default entries to these parameters.
+        *
+        * <p>
+        * Similar to {@link #set(String, Object)} but doesn't override 
existing values.
+        *
+        * @param pairs
+        *      The default entries.
+        *      <br>Can be <jk>null</jk>.
+        * @return This object (for method chaining).
+        */
+       public RequestQueryParams addDefault(NameValuePair...pairs) {
+               return addDefault(Arrays.asList(pairs));
+       }
+
+       /**
         * Returns all the parameters with the specified name.
         *
         * @param name The parameter name.
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationContext.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationContext.java
index 324b8d6..f91bca9 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationContext.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperationContext.java
@@ -1868,7 +1868,7 @@ public class RestOperationContext extends BeanContext 
implements Comparable<Rest
                                output = 
methodInvoker.invoke(context.getResource(), args);
 
                                // Handle manual call to req.setDebug().
-                               Boolean debug = 
ObjectUtils.castOrNull(req.getAttribute("Debug"), Boolean.class);
+                               Boolean debug = 
req.getAttribute("Debug").asType(Boolean.class).orElse(null);
                                if (debug == Boolean.TRUE) {
                                        call.debug(true);
                                } else if (debug == Boolean.FALSE) {
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
index f585979..aa558c9 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
@@ -1036,8 +1036,8 @@ public final class RestRequest {
         * @param name The attribute name.
         * @return The attribute value, never <jk>null</jk>.
         */
-       public Optional<Object> getAttribute(String name) {
-               return Optional.ofNullable(attrs.get(name));
+       public RequestAttribute getAttribute(String name) {
+               return attrs.get(name);
        }
 
        /**
@@ -1047,7 +1047,7 @@ public final class RestRequest {
         * @param value The attribute value.
         */
        public void setAttribute(String name, Object value) {
-               attrs.put(name, value);
+               attrs.set(name, value);
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
@@ -1689,8 +1689,7 @@ public final class RestRequest {
         * @return <jk>true</jk> if debug mode is enabled.
         */
        public boolean isDebug() {
-               Boolean b = 
ObjectUtils.castOrNull(getAttribute("Debug").orElse(null), Boolean.class);
-               return b == null ? false : b;
+               return 
getAttribute("Debug").asType(Boolean.class).orElse(false);
        }
 
        /**
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/args/AttributeArg.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/args/AttributeArg.java
index 0466f90..fc16f7a 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/args/AttributeArg.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/args/AttributeArg.java
@@ -14,8 +14,6 @@ package org.apache.juneau.rest.args;
 
 import static org.apache.juneau.internal.StringUtils.*;
 
-import java.lang.reflect.*;
-
 import org.apache.juneau.reflect.*;
 import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
@@ -24,12 +22,12 @@ import org.apache.juneau.rest.annotation.*;
  * Resolves method parameters annotated with {@link Attr} on {@link 
RestOp}-annotated Java methods.
  *
  * <p>
- * The parameter value is resolved using <c><jv>call</jv>.{@link 
RestCall#getRestRequest() getRestRequest}().{@link RestRequest#getAttributes() 
getAttributes}().{@link RequestAttributes#get(String,Type,Type...) 
get}(<jv>name</jv>,<jv>type</jv>)</c>.
+ * The parameter value is resolved using <c><jv>call</jv>.{@link 
RestCall#getRestRequest() getRestRequest}().{@link RestRequest#getAttributes() 
getAttributes}().{@link RequestAttributes#get(String) 
get}(<jv>name</jv>).{@link RequestAttribute#asType(Class) asType}(<jv>type</jv>.
  */
 public class AttributeArg implements RestOperationArg {
 
        private final String name;
-       private final Type type;
+       private final Class<?> type;
 
        /**
         * Static creator.
@@ -50,7 +48,7 @@ public class AttributeArg implements RestOperationArg {
         */
        protected AttributeArg(ParamInfo paramInfo) {
                this.name = getName(paramInfo);
-               this.type = paramInfo.getParameterType().innerType();
+               this.type = paramInfo.getParameterType().inner();
        }
 
        private String getName(ParamInfo paramInfo) {
@@ -66,6 +64,6 @@ public class AttributeArg implements RestOperationArg {
 
        @Override /* RestOperationArg */
        public Object resolve(RestCall call) throws Exception {
-               return call.getRestRequest().getAttributes().get(name, type);
+               return 
call.getRestRequest().getAttribute(name).asType(type).orElse(null);
        }
 }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/DefaultHandler.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/DefaultHandler.java
index 7437d13..94fc565 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/DefaultHandler.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/DefaultHandler.java
@@ -175,7 +175,7 @@ public class DefaultHandler implements ResponseHandler {
                                SerializerSession session = s.createSession(
                                        SerializerSessionArgs
                                                .create()
-                                               .properties(req.getAttributes())
+                                               
.properties(req.getAttributes().asMap())
                                                
.javaMethod(req.getOpContext().getJavaMethod())
                                                .locale(req.getLocale())
                                                
.timeZone(req.getTimeZone().orElse(null))
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/UrlPathMatch.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/UrlPathMatch.java
index d0c3eb0..8543e3f 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/UrlPathMatch.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/UrlPathMatch.java
@@ -66,7 +66,6 @@ public class UrlPathMatch {
                return ! vars.isEmpty();
        }
 
-
        /**
         * Returns <jk>true</jk> if any of the variable values are blank.
         *
@@ -82,6 +81,9 @@ public class UrlPathMatch {
        /**
         * Returns the remainder of the path after the pattern match has been 
made.
         *
+        * <p>
+        * Same as {#link {@link #getSuffix()} but trims the leading slash if 
there is one.
+        *
         * @return The remainder of the path after the pattern match has been 
made.
         */
        public String getRemainder() {
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/RequestAttributeVar.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/RequestAttributeVar.java
index 77a1317..923eb65 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/RequestAttributeVar.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/RequestAttributeVar.java
@@ -12,8 +12,6 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.rest.vars;
 
-import static org.apache.juneau.internal.StringUtils.*;
-
 import javax.servlet.http.*;
 
 import org.apache.juneau.http.exception.*;
@@ -72,7 +70,7 @@ public class RequestAttributeVar extends 
MultipartResolvingVar {
        @Override /* Var */
        public String resolve(VarResolverSession session, String key) {
                RestRequest req = 
session.getBean(RestRequest.class).orElseThrow(InternalServerError::new);
-               return stringify(req.getAttribute(key));
+               return req.getAttribute(key).asString().orElse(null);
        }
 
        @Override /* Var */
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/RequestVar.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/RequestVar.java
index c721e9c..5bf8339 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/RequestVar.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/RequestVar.java
@@ -111,7 +111,7 @@ public class RequestVar extends MultipartResolvingVar {
                        if ("servletURI".equals(key))
                                return 
req.getUriContext().getRootRelativeServletPath();
                }
-               return req.getAttributes().getString(key);
+               return req.getAttributes().get(key).asString().orElse(null);
        }
 
        @Override /* Var */
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java
index 2822db4..1227311 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java
@@ -57,9 +57,7 @@ public class SerializedRequestAttrVar extends StreamedVar {
                        throw new RuntimeException("Invalid format for $SA var. 
 Must be of the format $SA{contentType,key[,defaultValue]}");
                String[] s2 = split(key);
                RestRequest req = 
session.getBean(RestRequest.class).orElseThrow(InternalServerError::new);
-               Object o = req.getAttribute(key);
-               if (o == null)
-                       o = key;
+               Object o = req.getAttribute(key).orElse(key);
                Serializer s = 
req.getOpContext().getSerializers().getSerializer(s2[0]);
                if (s != null)
                        s.serialize(w, o);
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/MenuItemWidget.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/MenuItemWidget.java
index aa7063e..1f2b4b3 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/MenuItemWidget.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/MenuItemWidget.java
@@ -155,7 +155,7 @@ public abstract class MenuItemWidget extends Widget {
                        SerializerSessionArgs args =
                                SerializerSessionArgs
                                        .create()
-                                       .properties(req.getAttributes())
+                                       .properties(req.getAttributes().asMap())
                                        .debug(req.isDebug() ? true : null)
                                        .uriContext(req.getUriContext())
                                        .useWhitespace(req.isPlainText() ? true 
: null)
@@ -172,7 +172,7 @@ public abstract class MenuItemWidget extends Widget {
        }
 
        private Integer getId(RestRequest req) {
-               Integer id = 
(Integer)req.getAttribute("LastMenuItemId").orElse(0) + 1;
+               Integer id = 
req.getAttribute("LastMenuItemId").asType(Integer.class).orElse(0) + 1;
                req.setAttribute("LastMenuItemId", id);
                return id;
        }
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHook_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHook_Test.java
index ee7a9b8..b4d326c 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHook_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHook_Test.java
@@ -55,9 +55,9 @@ public class RestHook_Test {
                @RestHook(PRE_CALL)
                public void onPreCall(RestRequest req) {
                        RequestAttributes attrs = req.getAttributes();
-                       attrs.put("p2", "xp2");
-                       attrs.put("p4", "xp4");
-                       attrs.put("p5", "xp5"); // New property
+                       attrs.set("p2", "xp2");
+                       attrs.set("p4", "xp4");
+                       attrs.set("p5", "xp5"); // New property
                        String overrideContentType = 
req.getHeader("Override-Content-Type").orElse(null);
                        if (overrideContentType != null)
                                req.getHeaders().set("Content-Type", 
overrideContentType);
@@ -75,8 +75,8 @@ public class RestHook_Test {
 
                @RestPut
                public String b(RestRequest req, RequestAttributes attrs) 
throws Exception {
-                       attrs.put("p3", "pp3");
-                       attrs.put("p4", "pp4");
+                       attrs.set("p3", "pp3");
+                       attrs.set("p4", "pp4");
                        return req.getBody().asType(String.class);
                }
        }
@@ -125,15 +125,15 @@ public class RestHook_Test {
                @RestHook(POST_CALL)
                public void onPostCall(RestRequest req, RestResponse res) {
                        RequestAttributes attrs = req.getAttributes();
-                       attrs.put("p2", "xp2");
-                       attrs.put("p4", "xp4");
-                       attrs.put("p5", "xp5"); // New property
+                       attrs.set("p2", "xp2");
+                       attrs.set("p4", "xp4");
+                       attrs.set("p5", "xp5"); // New property
                        String overrideAccept = 
req.getHeader("Override-Accept").orElse(null);
                        if (overrideAccept != null)
                                req.getHeaders().set("Accept", overrideAccept);
                        String overrideContentType = 
req.getHeader("Override-Content-Type").orElse(null);
                        if (overrideContentType != null)
-                               attrs.put("Override-Content-Type", 
overrideContentType);
+                               attrs.set("Override-Content-Type", 
overrideContentType);
                }
 
                @RestPut(
@@ -149,8 +149,8 @@ public class RestHook_Test {
 
                @RestPut
                public String b(RestRequest req, RequestAttributes attrs) 
throws Exception {
-                       attrs.put("p3", "pp3");
-                       attrs.put("p4", "pp4");
+                       attrs.set("p3", "pp3");
+                       attrs.set("p4", "pp4");
                        String accept = req.getHeader("Accept").orElse(null);
                        if (accept == null || accept.isEmpty())
                                req.getHeaders().set("Accept", "text/s2");
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_RVars_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_RVars_Test.java
index aaec5f5..34b0335 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_RVars_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_RVars_Test.java
@@ -83,6 +83,6 @@ public class Rest_RVars_Test {
        @Test
        public void a01_basic() throws Exception {
                RestClient a = MockRestClient.build(A.class);
-               
a.get("/p2").accept("text/plain").run().assertBody().is("A1=a1,A2=c,B1=b1,B2=c,C=c,R1a=/p1/p2,R1b=/p1,R2=bar,R3=,R4=a1,R5=c,R6=c");
+               
a.get("/p2").accept("text/plain").run().assertBody().is("A1=a1,A2=c,B1=b1,B2=c,C=c,R1a=/p1/p2,R1b=/p1,R2=bar,R3=,R4=a1,R5=a2,R6=");
        }
 }
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Restx_ReqAttrs_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Restx_ReqAttrs_Test.java
index ac451dc..7ca39f9 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Restx_ReqAttrs_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Restx_ReqAttrs_Test.java
@@ -48,11 +48,11 @@ public class Restx_ReqAttrs_Test {
                        // Should show 
{p1:'v1',p2:'v2a',p3:'v3',p4:'v4a',p5:'v5'} when override is false.
                        // Should show {p1:'x',p2:'x',p3:'x',p4:'x',p5:'x'} 
when override is true.
                        if (override) {
-                               attrs.put("p1", "x");
-                               attrs.put("p2", "x");
-                               attrs.put("p3", "x");
-                               attrs.put("p4", "x");
-                               attrs.put("p5", "x");
+                               attrs.set("p1", "x");
+                               attrs.set("p2", "x");
+                               attrs.set("p3", "x");
+                               attrs.set("p4", "x");
+                               attrs.set("p5", "x");
                        }
                        return transform(attrs);
                }
@@ -67,11 +67,11 @@ public class Restx_ReqAttrs_Test {
                        // Should show 
{p1:'v1',p2:'v2a',p3:'v3',p4:'v4a',p5:'v5'} when override is false.
                        // Should show {p1:'x',p2:'x',p3:'x',p4:'x',p5:'x'} 
when override is true.
                        if (override) {
-                               attrs.put("p1", "x");
-                               attrs.put("p2", "x");
-                               attrs.put("p3", "x");
-                               attrs.put("p4", "x");
-                               attrs.put("p5", "x");
+                               attrs.set("p1", "x");
+                               attrs.set("p2", "x");
+                               attrs.set("p3", "x");
+                               attrs.set("p4", "x");
+                               attrs.set("p5", "x");
                        }
                        return transform(attrs);
                }
@@ -86,11 +86,11 @@ public class Restx_ReqAttrs_Test {
                        // Should show 
{p1:'v1',p2:'v2a',p3:'v3',p4:'v4a',p5:'v5'} when override is false.
                        // Should show {p1:'x',p2:'x',p3:'x',p4:'x',p5:'x'} 
when override is true.
                        if (override) {
-                               attrs.put("p1", "x");
-                               attrs.put("p2", "x");
-                               attrs.put("p3", "x");
-                               attrs.put("p4", "x");
-                               attrs.put("p5", "x");
+                               attrs.set("p1", "x");
+                               attrs.set("p2", "x");
+                               attrs.set("p3", "x");
+                               attrs.set("p4", "x");
+                               attrs.set("p5", "x");
                        }
                        return transform(attrs);
                }
@@ -105,11 +105,11 @@ public class Restx_ReqAttrs_Test {
                        // Should show 
{p1:'v1',p2:'v2a',p3:'v3',p4:'v4a',p5:'v5'} when override is false.
                        // Should show {p1:'x',p2:'x',p3:'x',p4:'x',p5:'x'} 
when override is true.
                        if (override) {
-                               attrs.put("p1", "x");
-                               attrs.put("p2", "x");
-                               attrs.put("p3", "x");
-                               attrs.put("p4", "x");
-                               attrs.put("p5", "x");
+                               attrs.set("p1", "x");
+                               attrs.set("p2", "x");
+                               attrs.set("p3", "x");
+                               attrs.set("p4", "x");
+                               attrs.set("p5", "x");
                        }
                        return transform(attrs);
                }
@@ -124,18 +124,18 @@ public class Restx_ReqAttrs_Test {
                        // Should show 
{p1:'v1',p2:'v2a',p3:'v3',p4:'v4a',p5:'v5'} when override is false.
                        // Should show {p1:'x',p2:'x',p3:'x',p4:'x',p5:'x'} 
when override is true.
                        if (override) {
-                               attrs.put("p1", "x");
-                               attrs.put("p2", "x");
-                               attrs.put("p3", "x");
-                               attrs.put("p4", "x");
-                               attrs.put("p5", "x");
+                               attrs.set("p1", "x");
+                               attrs.set("p2", "x");
+                               attrs.set("p3", "x");
+                               attrs.set("p4", "x");
+                               attrs.set("p5", "x");
                        }
                        return transform(attrs);
                }
 
                private OMap transform(RequestAttributes attrs) {
                        OMap m = new OMap();
-                       for (Map.Entry<String,Object> e : attrs.entrySet()) {
+                       for (Map.Entry<String,Object> e : 
attrs.asMap().entrySet()) {
                                if (e.getKey().startsWith("p"))
                                        m.put(e.getKey(), e.getValue());
                        }

Reply via email to