Skip to content

Commit 10ed7b1

Browse files
authored
Merge pull request #44421 from mariofusco/q44417
Fix deserialization of null maps in reflection-free Jackson deserializers
2 parents 6329fda + f23faa2 commit 10ed7b1

File tree

5 files changed

+63
-10
lines changed

5 files changed

+63
-10
lines changed

extensions/resteasy-reactive/rest-jackson/deployment/src/main/java/io/quarkus/resteasy/reactive/jackson/deployment/processor/JacksonDeserializerFactory.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -239,18 +239,18 @@ private boolean deserializeObject(ClassInfo classInfo, ResultHandle objHandle, C
239239
ResultHandle nextField = loopCreator
240240
.invokeInterfaceMethod(ofMethod(Iterator.class, "next", Object.class), fieldsIterator);
241241
ResultHandle mapEntry = loopCreator.checkCast(nextField, Map.Entry.class);
242-
ResultHandle fieldName = loopCreator
243-
.invokeInterfaceMethod(ofMethod(Map.Entry.class, "getKey", Object.class), mapEntry);
244242
ResultHandle fieldValue = loopCreator.checkCast(loopCreator
245243
.invokeInterfaceMethod(ofMethod(Map.Entry.class, "getValue", Object.class), mapEntry), JsonNode.class);
246244

247-
loopCreator.ifTrue(loopCreator.invokeVirtualMethod(ofMethod(JsonNode.class, "isNull", boolean.class), fieldValue))
248-
.trueBranch().continueScope(loopCreator);
245+
BytecodeCreator fieldReader = loopCreator
246+
.ifTrue(loopCreator.invokeVirtualMethod(ofMethod(JsonNode.class, "isNull", boolean.class), fieldValue))
247+
.falseBranch();
248+
249+
ResultHandle fieldName = fieldReader
250+
.invokeInterfaceMethod(ofMethod(Map.Entry.class, "getKey", Object.class), mapEntry);
251+
Switch.StringSwitch strSwitch = fieldReader.stringSwitch(fieldName);
249252

250-
Set<String> deserializedFields = new HashSet<>();
251-
ResultHandle deserializationContext = deserialize.getMethodParam(1);
252-
Switch.StringSwitch strSwitch = loopCreator.stringSwitch(fieldName);
253-
return deserializeFields(classCreator, classInfo, deserializationContext, objHandle, fieldValue, deserializedFields,
253+
return deserializeFields(classCreator, classInfo, deserialize.getMethodParam(1), objHandle, fieldValue, new HashSet<>(),
254254
strSwitch, parseTypeParameters(classInfo, classCreator));
255255
}
256256

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package io.quarkus.resteasy.reactive.jackson.deployment.test;
2+
3+
import java.util.Map;
4+
5+
public class MapWrapper {
6+
7+
private String name;
8+
private Map<String, String> properties;
9+
10+
public MapWrapper() {
11+
}
12+
13+
public MapWrapper(String name) {
14+
this.name = name;
15+
}
16+
17+
public String getName() {
18+
return name;
19+
}
20+
21+
public void setName(String name) {
22+
this.name = name;
23+
}
24+
25+
public Map<String, String> getProperties() {
26+
return properties;
27+
}
28+
29+
public void setProperties(Map<String, String> properties) {
30+
this.properties = properties;
31+
}
32+
}

extensions/resteasy-reactive/rest-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/SimpleJsonResource.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,13 @@ public StateRecord echoDog(StateRecord stateRecord) {
123123
return stateRecord;
124124
}
125125

126+
@POST
127+
@Path("/null-map-echo")
128+
@Consumes(MediaType.APPLICATION_JSON)
129+
public MapWrapper echoNullMap(MapWrapper mapWrapper) {
130+
return mapWrapper;
131+
}
132+
126133
@EnableSecureSerialization
127134
@GET
128135
@Path("/abstract-cat")

extensions/resteasy-reactive/rest-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/SimpleJsonTest.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public JavaArchive get() {
3636
AbstractPet.class, Dog.class, Cat.class, Veterinarian.class, AbstractNamedPet.class,
3737
AbstractUnsecuredPet.class, UnsecuredPet.class, SecuredPersonInterface.class, Frog.class,
3838
Pond.class, FrogBodyParts.class, FrogBodyParts.BodyPart.class, ContainerDTO.class,
39-
NestedInterface.class, StateRecord.class)
39+
NestedInterface.class, StateRecord.class, MapWrapper.class)
4040
.addAsResource(new StringAsset("admin-expression=admin\n" +
4141
"user-expression=user\n" +
4242
"birth-date-roles=alice,bob\n"), "application.properties");
@@ -733,4 +733,18 @@ public void testRecordEcho() {
733733
assertTrue(first >= 0);
734734
assertEquals(first, last);
735735
}
736+
737+
@Test
738+
public void testNullMapEcho() {
739+
RestAssured
740+
.with()
741+
.body(new MapWrapper("test"))
742+
.contentType("application/json; charset=utf-8")
743+
.post("/simple/null-map-echo")
744+
.then()
745+
.statusCode(200)
746+
.contentType("application/json")
747+
.body("name", Matchers.is("test"))
748+
.body("properties", Matchers.nullValue());
749+
}
736750
}

extensions/resteasy-reactive/rest-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/SimpleJsonWithReflectionFreeSerializersTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public JavaArchive get() {
2525
AbstractPet.class, Dog.class, Cat.class, Veterinarian.class, AbstractNamedPet.class,
2626
AbstractUnsecuredPet.class, UnsecuredPet.class, SecuredPersonInterface.class, Frog.class,
2727
Pond.class, FrogBodyParts.class, FrogBodyParts.BodyPart.class, ContainerDTO.class,
28-
NestedInterface.class, StateRecord.class)
28+
NestedInterface.class, StateRecord.class, MapWrapper.class)
2929
.addAsResource(new StringAsset("admin-expression=admin\n" +
3030
"user-expression=user\n" +
3131
"birth-date-roles=alice,bob\n" +

0 commit comments

Comments
 (0)