From 6f91098a6d5aab533a1dc964976249d02649c052 Mon Sep 17 00:00:00 2001 From: gregw Date: Wed, 27 Nov 2024 09:57:37 +1100 Subject: [PATCH 1/3] Fix #12578 pretty print getParameterMap Fix #12578 pretty print getParameterMap Added test for parameters --- .../java/org/eclipse/jetty/util/Fields.java | 27 ++++++++++- .../jetty/ee10/servlet/RequestTest.java | 46 +++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java index f0015c70d0a0..50a2ce5fcaf9 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java @@ -14,6 +14,7 @@ package org.eclipse.jetty.util; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; @@ -329,7 +330,31 @@ public Iterator iterator() */ public Map toStringArrayMap() { - Map result = new LinkedHashMap<>(); + Map result = new LinkedHashMap<>() + { + @Override + public String toString() + { + if (fields.isEmpty()) + return "{}"; + + StringBuilder sb = new StringBuilder(); + sb.append('{'); + for (Iterator> i = entrySet().iterator(); i.hasNext();) + { + Map.Entry e = i.next(); + String key = e.getKey(); + String[] value = e.getValue(); + sb.append(key); + sb.append('='); + sb.append(Arrays.asList(value)); + if (i.hasNext()) + sb.append(','); + } + sb.append('}'); + return sb.toString(); + } + }; fields.forEach((k, f) -> result.put(f.getName(), f.getValues().toArray(new String[0]))); return result; } diff --git a/jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/RequestTest.java b/jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/RequestTest.java index 69d820b4d523..869717e28648 100644 --- a/jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/RequestTest.java +++ b/jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/RequestTest.java @@ -16,6 +16,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.Socket; @@ -626,4 +627,49 @@ protected void service(HttpServletRequest request, HttpServletResponse resp) thr assertThat(date, containsString(":")); } } + + @Test + public void testParameters() throws Exception + { + final AtomicReference parameterMap = new AtomicReference<>(); + + startServer(new HttpServlet() + { + @Override + protected void service(HttpServletRequest request, HttpServletResponse resp) throws IOException + { + parameterMap.set(request.getParameterMap().toString()); + PrintWriter out = resp.getWriter(); + out.println(request.getParameter("a")); + out.println(request.getParameterValues("a")[1]); + out.println(request.getParameterValues("a")[2]); + out.println(Arrays.asList(request.getParameterValues("b"))); + out.println(Arrays.asList(request.getParameterValues("c"))); + out.println(Arrays.asList(request.getParameterValues("d"))); + + } + }); + + String rawResponse = _connector.getResponse( + """ + POST /test/parameters?a=1&a=2&b=one&c= HTTP/1.1\r + Host: localhost\r + Connection: close\r + Content-Type: application/x-www-form-urlencoded\r + Content-Length: 23\r + \r + a=3&b=two&b=three&d=xyz\r + """); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + assertThat(parameterMap.get(), is("{a=[1, 2, 3],b=[one, two, three],c=[],d=[xyz]}")); + assertThat(response.getContent().replaceAll("\r\n","\n"), is(""" + 1 + 2 + 3 + [one, two, three] + [] + [xyz] + """)); + } } From fd5ae5860c31b560febb87aced2af9093b5ebfbc Mon Sep 17 00:00:00 2001 From: gregw Date: Thu, 28 Nov 2024 07:55:37 +1100 Subject: [PATCH 2/3] Fix #12578 pretty print getParameterMap Fix #12578 pretty print getParameterMap checkstyle --- .../test/java/org/eclipse/jetty/ee10/servlet/RequestTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/RequestTest.java b/jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/RequestTest.java index 869717e28648..4ee3dac98e9d 100644 --- a/jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/RequestTest.java +++ b/jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/RequestTest.java @@ -663,7 +663,7 @@ protected void service(HttpServletRequest request, HttpServletResponse resp) thr HttpTester.Response response = HttpTester.parseResponse(rawResponse); assertThat(response.getStatus(), is(HttpStatus.OK_200)); assertThat(parameterMap.get(), is("{a=[1, 2, 3],b=[one, two, three],c=[],d=[xyz]}")); - assertThat(response.getContent().replaceAll("\r\n","\n"), is(""" + assertThat(response.getContent().replaceAll("\r\n", "\n"), is(""" 1 2 3 From fdb07117e76bf9e40842c8fda026b3cfcf0de1aa Mon Sep 17 00:00:00 2001 From: gregw Date: Thu, 28 Nov 2024 11:34:15 +1100 Subject: [PATCH 3/3] Fix #12578 pretty print getParameterMap Fix #12578 pretty print getParameterMap Added TypeUtil method --- .../java/org/eclipse/jetty/util/Fields.java | 20 +---------- .../java/org/eclipse/jetty/util/MultiMap.java | 29 +-------------- .../java/org/eclipse/jetty/util/TypeUtil.java | 36 +++++++++++++++++++ .../org/eclipse/jetty/util/MultiMapTest.java | 6 ++-- 4 files changed, 41 insertions(+), 50 deletions(-) diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java index 50a2ce5fcaf9..b0a2842ea217 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java @@ -14,7 +14,6 @@ package org.eclipse.jetty.util; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; @@ -335,24 +334,7 @@ public Map toStringArrayMap() @Override public String toString() { - if (fields.isEmpty()) - return "{}"; - - StringBuilder sb = new StringBuilder(); - sb.append('{'); - for (Iterator> i = entrySet().iterator(); i.hasNext();) - { - Map.Entry e = i.next(); - String key = e.getKey(); - String[] value = e.getValue(); - sb.append(key); - sb.append('='); - sb.append(Arrays.asList(value)); - if (i.hasNext()) - sb.append(','); - } - sb.append('}'); - return sb.toString(); + return TypeUtil.toString(this); } }; fields.forEach((k, f) -> result.put(f.getName(), f.getValues().toArray(new String[0]))); diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/MultiMap.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/MultiMap.java index f9ce0f22a8cb..8a43a4325d3d 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/MultiMap.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/MultiMap.java @@ -15,7 +15,6 @@ import java.util.ArrayList; import java.util.Arrays; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -330,33 +329,7 @@ public boolean containsSimpleValue(V value) @Override public String toString() { - Iterator>> iter = entrySet().iterator(); - StringBuilder sb = new StringBuilder(); - sb.append('{'); - boolean delim = false; - while (iter.hasNext()) - { - Map.Entry> e = iter.next(); - if (delim) - { - sb.append(", "); - } - String key = e.getKey(); - List vals = e.getValue(); - sb.append(key); - sb.append('='); - if (vals.size() == 1) - { - sb.append(vals.get(0)); - } - else - { - sb.append(vals); - } - delim = true; - } - sb.append('}'); - return sb.toString(); + return TypeUtil.toString(this); } /** diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java index 7d0bdb94331f..995f5107285a 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java @@ -35,6 +35,7 @@ import java.util.Iterator; import java.util.List; import java.util.ListIterator; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.ServiceConfigurationError; @@ -864,4 +865,39 @@ public static boolean isDeclaredMethodOn(Object object, String methodName, Class return false; } } + + /** + * Pretty print a map. Specifically expanding Array values. + * @param map The map to render as a String + * @return A String representation of the map + */ + public static String toString(Map map) + { + if (map.isEmpty()) + return "{}"; + + StringBuilder sb = new StringBuilder(); + sb.append('{'); + for (Iterator> i = map.entrySet().iterator(); i.hasNext();) + { + Map.Entry e = i.next(); + Object key = e.getKey(); + sb.append(key); + sb.append('='); + + Object value = e.getValue(); + + if (value == null) + sb.append("null"); + else if (value.getClass().isArray()) + sb.append(Arrays.asList((Object[])value)); + else + sb.append(value); + if (i.hasNext()) + sb.append(','); + } + sb.append('}'); + return sb.toString(); + } + } diff --git a/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/MultiMapTest.java b/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/MultiMapTest.java index 45a430b714dc..fd2a350cfa17 100644 --- a/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/MultiMapTest.java +++ b/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/MultiMapTest.java @@ -462,12 +462,12 @@ public void testToString() MultiMap mm = new MultiMap<>(); mm.put("color", "red"); - assertEquals("{color=red}", mm.toString()); + assertEquals("{color=[red]}", mm.toString()); mm.putValues("food", "apple", "cherry", "raspberry"); - String expected1 = "{color=red, food=[apple, cherry, raspberry]}"; - String expected2 = "{food=[apple, cherry, raspberry], color=red}"; + String expected1 = "{color=[red],food=[apple, cherry, raspberry]}"; + String expected2 = "{food=[apple, cherry, raspberry],color=[red]}"; String actual = mm.toString(); assertTrue(actual.equals(expected1) || actual.equals(expected2)); }