From 75d5d4b33aeaa97ee177930f9169259235fda096 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Wed, 7 Dec 2022 13:23:23 +0000 Subject: [PATCH] Allow binding raw map to Map Closes gh-554 --- .../graphql/data/GraphQlArgumentBinder.java | 7 ++-- .../data/GraphQlArgumentBinderTests.java | 35 ++++++++++++++++++- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlArgumentBinder.java b/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlArgumentBinder.java index f31c8f4f..8688283e 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlArgumentBinder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlArgumentBinder.java @@ -245,10 +245,9 @@ public class GraphQlArgumentBinder { ArgumentsBindingResult bindingResult) { ResolvableType valueType = targetType.asMap().getGeneric(1); - Class valueClass = valueType.resolve(); - if (valueClass == null) { - bindingResult.rejectArgumentValue(name, null, "unknownType", "Unknown Map value type"); - return Collections.emptyMap(); // Keep going, to record more errors + Class valueClass = valueType.resolve(Object.class); + if (valueClass == Object.class) { + return rawMap; } Map map = CollectionFactory.createMap(targetClass, rawMap.size()); diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/GraphQlArgumentBinderTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/GraphQlArgumentBinderTests.java index e64c9ed3..c8f2ff2d 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/GraphQlArgumentBinderTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/GraphQlArgumentBinderTests.java @@ -318,7 +318,7 @@ class GraphQlArgumentBinderTests { } @Test - void primaryConstructorWithMapArgument() throws Exception { + void primaryConstructorWithItemMapArgument() throws Exception { Object result = bind( "{\"map\":{\"item1\":{\"name\":\"Jason\",\"age\":\"21\"},\"item2\":{\"name\":\"James\",\"age\":\"22\"}}}", @@ -336,6 +336,25 @@ class GraphQlArgumentBinderTests { assertThat(item2.getAge()).isEqualTo(22); } + @Test // gh-554 + void primaryConstructorWithRawMapArgument() throws Exception { + + Object result = bind( + "{\"map\":{\"item1\":{\"name\":\"Jason\",\"age\":\"21\"},\"item2\":{\"name\":\"James\",\"age\":\"22\"}}}", + ResolvableType.forClass(PrimaryConstructorRawMapBean.class)); + + assertThat(result).isNotNull().isInstanceOf(PrimaryConstructorRawMapBean.class); + Map map = ((PrimaryConstructorRawMapBean) result).getMap(); + + Map item1 = (Map) map.get("item1"); + assertThat(item1).containsEntry("name", "Jason"); + assertThat(item1).containsEntry("age", "21"); + + Map item2 = (Map) map.get("item2"); + assertThat(item2).containsEntry("name", "James"); + assertThat(item2).containsEntry("age", "22"); + } + @Test // gh-447 @SuppressWarnings("unchecked") void primaryConstructorWithGenericObject() throws Exception { @@ -476,6 +495,20 @@ class GraphQlArgumentBinderTests { } + static class PrimaryConstructorRawMapBean { + + private final Map map; + + public PrimaryConstructorRawMapBean(Map map) { + this.map = map; + } + + public Map getMap() { + return this.map; + } + } + + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") static class PrimaryConstructorOptionalItemBean {