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

commit 7db1ce5b2b489a53fd4d31c628d09a43f43df354
Author: JamesBognar <[email protected]>
AuthorDate: Fri Feb 12 17:47:20 2021 -0500

    REST refactoring.
---
 .../java/org/apache/juneau/rest/RequestHeader.java |  18 +-
 .../org/apache/juneau/rest/RequestHeaders.java     | 220 +++++++++++++--------
 .../java/org/apache/juneau/rest/RestRequest.java   |  19 +-
 .../juneau/http/SerializedHttpEntity_Test.java     |   2 +-
 .../org/apache/juneau/http/remote/Remote_Test.java |   2 +-
 .../annotation/Rest_AllowedHeaderParams_Test.java  |   2 +-
 .../rest/client/RestClient_BasicCalls_Test.java    |   2 +-
 .../juneau/rest/client/RestClient_Body_Test.java   |   6 +-
 .../client/RestClient_CallbackStrings_Test.java    |   4 +-
 .../client/RestClient_Config_BeanContext_Test.java |   2 +-
 .../client/RestClient_Config_OpenApi_Test.java     |   2 +-
 .../client/RestClient_Config_RestClient_Test.java  |   5 +-
 .../rest/client/RestClient_Headers_Test.java       |  12 +-
 .../client/RestClient_Response_Headers_Test.java   |   2 +-
 14 files changed, 168 insertions(+), 130 deletions(-)

diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestHeader.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestHeader.java
index 5c62f3c..e7ddfa6 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestHeader.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestHeader.java
@@ -55,7 +55,7 @@ public class RequestHeader implements Header {
                }
        };
 
-       private final Header header;
+       private final String name, value;
        private final RestRequest request;
        private HttpPartParserSession parser;
        private HttpPartSchema schema;
@@ -64,11 +64,13 @@ public class RequestHeader implements Header {
         * Constructor.
         *
         * @param request The request object.
-        * @param header The wrapped header.  Can be <jk>null</jk>.
+        * @param name The header name.
+        * @param value The header value.
         */
-       public RequestHeader(RestRequest request, Header header) {
+       public RequestHeader(RestRequest request, String name, String value) {
                this.request = request;
-               this.header = header == null ? NULL_HEADER : header;
+               this.name = name;
+               this.value = value;
                parser(null);
        }
 
@@ -117,7 +119,7 @@ public class RequestHeader implements Header {
         * @return <jk>true</jk> if this header exists on the response.
         */
        public boolean exists() {
-               return header != NULL_HEADER;
+               return value != null;
        }
 
        /**
@@ -720,7 +722,7 @@ public class RequestHeader implements Header {
         */
        @Override /* Header */
        public String getName() {
-               return header.getName();
+               return name;
        }
 
        /**
@@ -734,7 +736,7 @@ public class RequestHeader implements Header {
         */
        @Override /* Header */
        public String getValue() {
-               return header.getValue();
+               return value;
        }
 
        /**
@@ -745,7 +747,7 @@ public class RequestHeader implements Header {
         */
        @Override /* Header */
        public HeaderElement[] getElements() throws HttpException {
-               return header.getElements();
+               return new HeaderElement[0];
        }
 
        @Override /* Object */
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 ecbd58c..ffd5ffe 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
@@ -12,18 +12,19 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.rest;
 
-import static org.apache.juneau.internal.ArrayUtils.*;
 import static org.apache.juneau.internal.StringUtils.*;
 import static java.util.Collections.*;
+import static java.util.stream.Collectors.*;
 import static java.util.Optional.*;
+import static org.apache.juneau.assertions.Assertions.*;
 
 import java.util.*;
+import java.util.function.*;
 
 import org.apache.http.*;
 import org.apache.juneau.httppart.*;
 import org.apache.juneau.internal.*;
-import org.apache.juneau.json.*;
-import org.apache.juneau.http.*;
+import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.http.header.Date;
 
@@ -37,27 +38,76 @@ import org.apache.juneau.http.header.Date;
  *     <li class='link'>{@doc RestmRequestHeaders}
  * </ul>
  */
-public class RequestHeaders extends TreeMap<String,String[]> {
-       private static final long serialVersionUID = 1L;
+public class RequestHeaders {
 
        private final RestRequest req;
        private HttpPartParserSession parser;
-       private RequestQuery queryParams;
-       private Set<String> allowedQueryParams;
 
-       RequestHeaders(RestRequest req) {
-               super(String.CASE_INSENSITIVE_ORDER);
+       private List<RequestHeader> headers = new LinkedList<>();
+       private Map<String,List<RequestHeader>> headerMap = new TreeMap<>();
+
+       RequestHeaders(RestRequest req, RequestQuery query) {
                this.req = req;
+
+               for (Enumeration<String> e = req.getHeaderNames(); 
e.hasMoreElements();) {
+                       String name = e.nextElement();
+                       String n = name.toLowerCase();
+                       List<RequestHeader> l = new ArrayList<>();
+                       for (Enumeration<String> ve = req.getHeaders(name); 
ve.hasMoreElements();) {
+                               RequestHeader h = new RequestHeader(req, name, 
ve.nextElement());
+                               headers.add(h);
+                               l.add(h);
+                       }
+                       headerMap.put(n, l);
+               }
+
+               Set<String> allowedHeaderParams = 
req.getContext().getAllowedHeaderParams();
+               if (allowedHeaderParams.contains("*")) {
+                       for (Map.Entry<String,String[]> e : query.entrySet()) {
+                               String name = e.getKey();
+                               String n = name.toLowerCase();
+                               List<RequestHeader> l = headerMap.get(n);
+                               if (l == null)
+                                       l = new ArrayList<>();
+                               for (String value : e.getValue()) {
+                                       RequestHeader h = new 
RequestHeader(req, name, value);
+                                       headers.add(h);
+                                       l.add(h);
+                               }
+                               headerMap.put(n, l);
+                       }
+
+               } else for (String name : allowedHeaderParams) {
+                       String n = name.toLowerCase();
+                       List<RequestHeader> l = headerMap.get(n);
+                       String[] values = query.get(name, true);
+                       if (values != null) {
+                               if (l == null)
+                                       l = new ArrayList<>();
+                               for (String value : values) {
+                                       RequestHeader h = new 
RequestHeader(req, name, value);
+                                       headers.add(h);
+                                       l.add(h);
+                               }
+                               headerMap.put(n, l);
+                       }
+               }
        }
 
-       RequestHeaders parser(HttpPartParserSession parser) {
+       /**
+        * Subset constructor.
+        */
+       RequestHeaders(RestRequest req, Map<String,List<RequestHeader>> 
headerMap, HttpPartParserSession parser) {
+               this.req = req;
+               this.headerMap.putAll(headerMap);
+               this.headers = 
headerMap.values().stream().flatMap(List::stream).collect(toList());
                this.parser = parser;
-               return this;
        }
 
-       RequestHeaders queryParams(RequestQuery queryParams, Set<String> 
allowedQueryParams) {
-               this.queryParams = queryParams;
-               this.allowedQueryParams = allowedQueryParams;
+       RequestHeaders parser(HttpPartParserSession parser) {
+               this.parser = parser;
+               for (RequestHeader h : headers)
+                       h.parser(parser);
                return this;
        }
 
@@ -74,30 +124,17 @@ public class RequestHeaders extends 
TreeMap<String,String[]> {
         */
        public RequestHeaders addDefault(List<Header> pairs) {
                for (Header p : pairs) {
-                       String key = p.getName();
-                       Object value = p.getValue();
-                       String[] v = get(key);
-                       if (v == null || v.length == 0 || 
StringUtils.isEmpty(v[0]))
-                               put(key, stringifyAll(value));
-               }
-               return this;
-       }
-
-       /**
-        * Adds a set of header values to this object.
-        *
-        * @param name The header name.
-        * @param values The header values.
-        * @return This object (for method chaining).
-        */
-       public RequestHeaders put(String name, Enumeration<String> values) {
-               // Optimized for enumerations of one entry, the most-common 
case.
-               if (values.hasMoreElements()) {
-                       String v = values.nextElement();
-                       String[] s = new String[]{v};
-                       while (values.hasMoreElements())
-                               s = append(s, values.nextElement());
-                       put(name, s);
+                       String name = p.getName();
+                       String n = name.toLowerCase();
+                       List<RequestHeader> l = headerMap.get(n);
+                       boolean hasAllBlanks = l != null && 
l.stream().allMatch(x -> StringUtils.isEmpty(x.getValue()));
+                       if (l == null || hasAllBlanks) {
+                               if (hasAllBlanks)
+                                       headers.removeAll(l);
+                               RequestHeader h = new RequestHeader(req, name, 
p.getValue());
+                               headers.add(h);
+                               headerMap.put(n, AList.of(h));
+                       }
                }
                return this;
        }
@@ -113,8 +150,9 @@ public class RequestHeaders extends 
TreeMap<String,String[]> {
         * @return The header.  Never <jk>null</jk>.
         */
        public RequestHeader getFirst(String name) {
-               String[] x = getValues(name);
-               return new RequestHeader(req, BasicHeader.of(name, x == null ? 
null : x[0]));
+               assertArgNotNull("name", name);
+               List<RequestHeader> l = headerMap.get(name.toLowerCase());
+               return (l == null || l.isEmpty() ? new RequestHeader(req, name, 
null).parser(parser) : l.get(0));
        }
 
        /**
@@ -128,8 +166,9 @@ public class RequestHeaders extends 
TreeMap<String,String[]> {
         * @return The header.  Never <jk>null</jk>.
         */
        public RequestHeader getLast(String name) {
-               String[] x = getValues(name);
-               return new RequestHeader(req, BasicHeader.of(name, x == null ? 
null : x[x.length-1]));
+               assertArgNotNull("name", name);
+               List<RequestHeader> l = headerMap.get(name.toLowerCase());
+               return (l == null || l.isEmpty() ? new RequestHeader(req, name, 
null).parser(parser) : l.get(l.size()-1));
        }
 
        /**
@@ -139,13 +178,9 @@ public class RequestHeaders extends 
TreeMap<String,String[]> {
         * @return The list of all headers with the specified name, or an empty 
list if none are found.
         */
        public List<RequestHeader> getAll(String name) {
-               String[] x = getValues(name);
-               if (x == null)
-                       return emptyList();
-               RequestHeader[] l = new RequestHeader[x.length];
-               for (int i = 0; i < x.length; i++)
-                       l[i] = new RequestHeader(req, BasicHeader.of(name, 
x[i]));
-               return Arrays.asList(l);
+               assertArgNotNull("name", name);
+               List<RequestHeader> l = headerMap.get(name.toLowerCase());
+               return unmodifiableList(l == null ? emptyList() : l);
        }
 
        /**
@@ -154,11 +189,7 @@ public class RequestHeaders extends 
TreeMap<String,String[]> {
         * @return All the headers in this request.
         */
        public List<RequestHeader> getAll() {
-               List<RequestHeader> l = new ArrayList<>();
-               for (Map.Entry<String,String[]> e : entrySet())
-                       for (String v : e.getValue())
-                               l.add(new RequestHeader(req, 
BasicHeader.of(e.getKey(), v)));
-               return l;
+               return unmodifiableList(headers);
        }
 
        /**
@@ -259,9 +290,39 @@ public class RequestHeaders extends 
TreeMap<String,String[]> {
         *
         * @param name The header name.
         * @param value The header value.
+        * @return This object (for method chaining).
         */
-       public void put(String name, Object value) {
-               super.put(name, stringifyAll(value));
+       public RequestHeaders put(String name, Object value) {
+               assertArgNotNull("name", name);
+               String n = name.toLowerCase();
+               RequestHeader h = new RequestHeader(req, name, 
stringify(value)).parser(parser);
+               if (headerMap.containsKey(n))
+                       headers.removeIf(x->x.getName().equalsIgnoreCase(name));
+               headers.add(h);
+               headerMap.put(n, AList.of(h));
+               return this;
+       }
+
+       /**
+        * Adds a request header value.
+        *
+        * <p>
+        * Header is added to the end of the headers.
+        *
+        * @param name The header name.
+        * @param value The header value.
+        * @return This object (for method chaining).
+        */
+       public RequestHeaders add(String name, Object value) {
+               assertArgNotNull("name", name);
+               String n = name.toLowerCase();
+               RequestHeader h = new RequestHeader(req, name, 
stringify(value)).parser(parser);
+               if (headerMap.containsKey(n))
+                       headerMap.get(n).add(h);
+               else
+                       headerMap.put(n, AList.of(h));
+               headers.add(h);
+               return this;
        }
 
        /**
@@ -271,11 +332,14 @@ public class RequestHeaders extends 
TreeMap<String,String[]> {
         * @return A new headers object.
         */
        public RequestHeaders subset(String...headers) {
-               RequestHeaders rh2 = new 
RequestHeaders(req).parser(parser).queryParams(queryParams, allowedQueryParams);
-               for (String h : headers)
-                       if (containsKey(h))
-                               rh2.put(h, get(h));
-               return rh2;
+               Map<String,List<RequestHeader>> m = Arrays
+                       .asList(headers)
+                       .stream()
+                       .map(x -> x.toLowerCase())
+                       .filter(headerMap::containsKey)
+                       .collect(toMap(Function.identity(),headerMap::get));
+
+               return new RequestHeaders(req, m, parser);
        }
 
        /**
@@ -793,36 +857,20 @@ public class RequestHeaders extends 
TreeMap<String,String[]> {
         * @return A JSON string containing the contents of the headers.
         */
        public String toString(boolean sorted) {
-               Map<String,Object> m = null;
-               if (sorted)
-                       m = new TreeMap<>();
-               else
-                       m = new LinkedHashMap<>();
-               for (Map.Entry<String,String[]> e : this.entrySet()) {
-                       String[] v = e.getValue();
-                       m.put(e.getKey(), v.length == 1 ? v[0] : v);
+               OMap m = OMap.create();
+               if (sorted) {
+                       for (List<RequestHeader> h1 : headerMap.values())
+                               for (RequestHeader h2 : h1)
+                                       m.append(h2.getName(), h2.getValue());
+               } else {
+                       for (RequestHeader h : headers)
+                               m.append(h.getName(), h.getValue());
                }
-               return SimpleJsonSerializer.DEFAULT.toString(m);
+               return m.toString();
        }
 
        @Override /* Object */
        public String toString() {
                return toString(false);
        }
-
-       
//-----------------------------------------------------------------------------------------------------------------
-       // Helper methods
-       
//-----------------------------------------------------------------------------------------------------------------
-
-       private String[] getValues(String name) {
-               String[] v = null;
-               if (queryParams != null)
-                       if (allowedQueryParams.contains("*") || 
allowedQueryParams.contains(name))
-                               v = queryParams.get(name, true);
-               if (v == null || v.length == 0)
-                       v = get(name);
-               if (v == null || v.length == 0)
-                       return null;
-               return v;
-       }
 }
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 7f25168..0e32c1c 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
@@ -21,6 +21,7 @@ import static org.apache.juneau.internal.IOUtils.*;
 import static org.apache.juneau.serializer.Serializer.*;
 import static org.apache.juneau.rest.HttpRuntimeException.*;
 import static java.lang.Integer.*;
+import static java.util.Collections.*;
 
 import java.io.*;
 import java.lang.reflect.*;
@@ -31,6 +32,7 @@ import java.nio.charset.*;
 import java.text.*;
 import java.util.*;
 import java.util.logging.*;
+import java.util.stream.*;
 
 import javax.servlet.*;
 import javax.servlet.http.*;
@@ -141,11 +143,7 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
                queryParams = new RequestQuery(this);
                queryParams.putAll(call.getQueryParams());
 
-               headers = new RequestHeaders(this);
-               for (Enumeration<String> e = getHeaderNames(); 
e.hasMoreElements();) {
-                       String name = e.nextElement();
-                       headers.put(name, super.getHeaders(name));
-               }
+               headers = new RequestHeaders(this, queryParams);
 
                body = new RequestBody(this);
 
@@ -157,10 +155,6 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
                        }
                }
 
-               Set<String> s = context.getAllowedHeaderParams();
-               if (! s.isEmpty())
-                       headers.queryParams(queryParams, s);
-
                pathParams = new RequestPath(this);
                pathParams.putAll(call.getPathVars());
 
@@ -246,7 +240,7 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
         * @return The header.  Never <jk>null</jk>.
         */
        public RequestHeader getRequestHeader(String name) {
-               return new RequestHeader(this, 
headers.getLast(name)).parser(getPartParserSession());
+               return headers.getLast(name).parser(getPartParserSession());
        }
 
        /**
@@ -529,10 +523,7 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
 
        @Override /* ServletRequest */
        public Enumeration<String> getHeaders(String name) {
-               String[] v = headers.get(name);
-               if (v == null || v.length == 0)
-                       return Collections.enumeration(Collections.EMPTY_LIST);
-               return Collections.enumeration(Arrays.asList(v));
+               return inner.getHeaders(name);
        }
 
        /**
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/http/SerializedHttpEntity_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/http/SerializedHttpEntity_Test.java
index a88a829..05b536a 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/http/SerializedHttpEntity_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/http/SerializedHttpEntity_Test.java
@@ -41,7 +41,7 @@ public class SerializedHttpEntity_Test {
        public static class A extends BasicRestObject {
                @RestOp
                public String[] 
postCheckHeader(org.apache.juneau.rest.RestRequest req) {
-                       return 
req.getRequestHeaders().get(req.getHeader("Check"));
+                       return 
req.getRequestHeaders().getAll(req.getHeader("Check")).stream().map(x -> 
x.getValue()).toArray(String[]::new);
                }
                @RestOp
                public Reader postCheckBody(org.apache.juneau.rest.RestRequest 
req) throws IOException {
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_Test.java 
b/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_Test.java
index 49e0dff..54072e0 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_Test.java
@@ -521,7 +521,7 @@ public class Remote_Test {
        public static class F extends BasicRestObject {
                @RestOp
                public String[] getHeaders(org.apache.juneau.rest.RestRequest 
req) {
-                       return 
req.getRequestHeaders().get(req.getHeader("Check"));
+                       return 
req.getRequestHeaders().getAll(req.getHeader("Check")).stream().map(x -> 
x.getValue()).toArray(String[]::new);
                }
        }
 
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_AllowedHeaderParams_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_AllowedHeaderParams_Test.java
index a9d2a26..e29767f 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_AllowedHeaderParams_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_AllowedHeaderParams_Test.java
@@ -38,7 +38,7 @@ public class Rest_AllowedHeaderParams_Test {
                }
        }
 
-       @Rest()
+       @Rest() /* Default is allowedHeaderParams="Accept, Content-Type" */
        public static class A1 extends A {}
 
        @Rest(allowedHeaderParams="Accept, Content-Type")
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_BasicCalls_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_BasicCalls_Test.java
index 8e5b64f..648b1b3 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_BasicCalls_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_BasicCalls_Test.java
@@ -83,7 +83,7 @@ public class RestClient_BasicCalls_Test {
                }
                @RestOp(path="/checkHeader")
                public String[] postHeader(org.apache.juneau.rest.RestRequest 
req) {
-                       return 
req.getRequestHeaders().get(req.getHeader("Check"));
+                       return 
req.getRequestHeaders().getAll(req.getHeader("Check")).stream().map(x -> 
x.getValue()).toArray(String[]::new);
                }
                @RestOp(path="/",method="*")
                public Reader echoMethod(@Method String method) {
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Body_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Body_Test.java
index e866be4..06271e4 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Body_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Body_Test.java
@@ -36,10 +36,8 @@ public class RestClient_Body_Test {
        public static class A extends BasicRestObject {
                @RestOp
                public Reader post(org.apache.juneau.rest.RestRequest req, 
org.apache.juneau.rest.RestResponse res) throws IOException {
-                       for (Map.Entry<String,String[]> e : 
req.getRequestHeaders().entrySet()) {
-                               for (String v : e.getValue())
-                                       res.addHeader("X-" + e.getKey(), v);
-                       }
+                       for (RequestHeader e : req.getRequestHeaders().getAll())
+                               res.addHeader("X-" + e.getName(), e.getValue());
                        return req.getReader();
                }
        }
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_CallbackStrings_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_CallbackStrings_Test.java
index a633f42..ae9926e 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_CallbackStrings_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_CallbackStrings_Test.java
@@ -43,9 +43,7 @@ public class RestClient_CallbackStrings_Test {
                }
                private Map<String,Object> getFooHeaders(RestRequest req) {
                        Map<String,Object> m = new TreeMap<>();
-                       for (Map.Entry<String,String[]> e : 
req.getRequestHeaders().entrySet())
-                               if (e.getKey().startsWith("Foo-"))
-                                       m.put(e.getKey(),e.getValue()[0]);
+                       req.getRequestHeaders().getAll().stream().filter(x -> 
x.getName().startsWith("Foo-")).forEach(x -> m.put(x.getName(), x.getValue()));
                        return m;
                }
        }
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_BeanContext_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_BeanContext_Test.java
index 5dd9dc36..4da7d9b 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_BeanContext_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_BeanContext_Test.java
@@ -41,7 +41,7 @@ public class RestClient_Config_BeanContext_Test {
                }
                @RestOp(path="/checkHeader")
                public String[] getHeader(org.apache.juneau.rest.RestRequest 
req) {
-                       return 
req.getRequestHeaders().get(req.getHeader("Check"));
+                       return 
req.getRequestHeaders().getAll(req.getHeader("Check")).stream().map(x -> 
x.getValue()).toArray(String[]::new);
                }
                @RestOp(path="/checkQuery")
                public Reader getQuery(org.apache.juneau.rest.RestRequest req) {
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_OpenApi_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_OpenApi_Test.java
index f8b0047..3f7ce80 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_OpenApi_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_OpenApi_Test.java
@@ -36,7 +36,7 @@ public class RestClient_Config_OpenApi_Test {
                }
                @RestOp(path="/checkHeader")
                public String[] getHeader(org.apache.juneau.rest.RestRequest 
req) {
-                       return 
req.getRequestHeaders().get(req.getHeader("Check"));
+                       return 
req.getRequestHeaders().getAll(req.getHeader("Check")).stream().map(x -> 
x.getValue()).toArray(String[]::new);
                }
                @RestOp(path="/checkQuery")
                public Reader getQuery(org.apache.juneau.rest.RestRequest req) {
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_RestClient_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_RestClient_Test.java
index 3598f58..f953e60 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_RestClient_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_RestClient_Test.java
@@ -20,6 +20,7 @@ import static org.junit.runners.MethodSorters.*;
 import java.io.*;
 import java.util.concurrent.*;
 import java.util.logging.*;
+import java.util.stream.*;
 
 import org.apache.http.*;
 import org.apache.http.HttpResponse;
@@ -85,7 +86,7 @@ public class RestClient_Config_RestClient_Test {
                }
                @RestOp(path="/checkHeader")
                public String[] getHeader(org.apache.juneau.rest.RestRequest 
req) {
-                       return 
req.getRequestHeaders().get(req.getHeader("Check"));
+                       return 
req.getRequestHeaders().getAll(req.getHeader("Check")).stream().map(x -> 
x.getValue()).toArray(String[]::new);
                }
        }
 
@@ -445,7 +446,7 @@ public class RestClient_Config_RestClient_Test {
                @RestOp(path="/")
                public Ok get(@Header(name="Foo",multi=true) ABean[] 
foo,org.apache.juneau.rest.RestRequest req,org.apache.juneau.rest.RestResponse 
res) throws Exception {
                        assertEquals(2,foo.length);
-                       
assertObject(req.getRequestHeaders().get("Foo")).asJson().is("['x{f:1}','x{f:1}']");
+                       
assertObject(req.getRequestHeaders().getAll("Foo").stream().map(RequestHeader::getValue).collect(Collectors.toList())).asJson().is("['x{f:1}','x{f:1}']");
                        assertEquals("{f:1}",foo[0].toString());
                        assertEquals("{f:1}",foo[1].toString());
                        res.header("Foo",bean);
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Headers_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Headers_Test.java
index 872221d..0c935c0 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Headers_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Headers_Test.java
@@ -58,7 +58,7 @@ public class RestClient_Headers_Test {
        public static class A extends BasicRestObject {
                @RestOp
                public String[] getHeaders(org.apache.juneau.rest.RestRequest 
req) {
-                       return 
req.getRequestHeaders().get(req.getHeader("Check"));
+                       return 
req.getRequestHeaders().getAll(req.getHeader("Check")).stream().map(x -> 
x.getValue()).toArray(String[]::new);
                }
        }
 
@@ -77,10 +77,10 @@ public class RestClient_Headers_Test {
                
checkFooClient().build().get("/headers").header("Foo","baz").run().assertBody().is("['baz']");
                
checkFooClient().header("Foo","bar").build().get("/headers").header("Foo","baz").run().assertBody().is("['bar','baz']");
                
checkFooClient().header("Foo",bean).build().get("/headers").header("Foo",bean).run().assertBody().is("['f=1','f=1']");
-               
checkFooClient().header("Foo",null).build().get("/headers").header("Foo",null).run().assertBody().is("null");
+               
checkFooClient().header("Foo",null).build().get("/headers").header("Foo",null).run().assertBody().is("[]");
 
-               
checkClient("null").header(null,"bar").build().get("/headers").header(null,"Foo").run().assertBody().is("null");
-               
checkClient("null").header(null,null).build().get("/headers").header(null,null).run().assertBody().is("null");
+               
checkClient("null").header(null,"bar").build().get("/headers").header(null,"Foo").run().assertBody().is("[]");
+               
checkClient("null").header(null,null).build().get("/headers").header(null,null).run().assertBody().is("[]");
        }
 
        @Test
@@ -105,7 +105,7 @@ public class RestClient_Headers_Test {
 
        @Test
        public void a06_headers_Objects() throws Exception {
-               
checkFooClient().headers((Header)null).build().get("/headers").headers((Header)null).run().assertBody().is("null");
+               
checkFooClient().headers((Header)null).build().get("/headers").headers((Header)null).run().assertBody().is("[]");
                
checkFooClient().headers(header("Foo","bar"),header("Baz","baz")).build().get("/headers").headers(header("Foo","baz"),header("Baz","quux")).run().assertBody().is("['bar','baz']");
                
checkFooClient().headers(OMap.of("Foo","bar")).build().get("/headers").headers(OMap.of("Foo","baz")).run().assertBody().is("['bar','baz']");
                
checkFooClient().headers(AMap.of("Foo","bar")).build().get("/headers").headers(AMap.of("Foo","baz")).run().assertBody().is("['bar','baz']");
@@ -117,7 +117,7 @@ public class RestClient_Headers_Test {
                
checkFooClient().headers(HeaderSupplier.of(header("Foo","bar"))).build().get("/headers").headers(HeaderSupplier.of(header("Foo","baz"))).run().assertBody().is("['bar','baz']");
                
checkFooClient().headers(AList.of(header("Foo","bar"))).build().get("/headers").headers(AList.of(header("Foo","baz"))).run().assertBody().is("['bar','baz']");
                
checkClient("f").build().get("/headers").headers(bean).run().assertBody().is("['1']");
-               
checkClient("f").build().get("/headers").headers((Object)null).run().assertBody().is("null");
+               
checkClient("f").build().get("/headers").headers((Object)null).run().assertBody().is("[]");
                assertThrown(()->client().headers("Foo")).contains("Invalid 
type");
                
assertThrown(()->client().build().get("").headers("Foo")).contains("Invalid 
type");
 
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Headers_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Headers_Test.java
index 1056742..ec09d09 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Headers_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Headers_Test.java
@@ -37,7 +37,7 @@ public class RestClient_Response_Headers_Test {
                @RestOp
                public String getEcho(org.apache.juneau.rest.RestRequest req, 
org.apache.juneau.rest.RestResponse res) {
                        String c = req.getHeader("Check");
-                       String[] h = req.getRequestHeaders().get(c);
+                       String[] h = 
req.getRequestHeaders().getAll(req.getHeader("Check")).stream().map(x -> 
x.getValue()).toArray(String[]::new);
                        if (h != null)
                                for (String hh : h)
                                        res.addHeader(c, hh);

Reply via email to