forked from quarkusio/quarkus
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Jackson: also detect class referenced by
@JsonTypeIdResolver
Adds missing support for classes referenced by `@JsonTypeIdResolver`, which is particularly important when using native builds. The added integration tests are likely only meaningful when run in native mode (`-Pnative`), otherwise "good old Java reflection" does its job. Fixes quarkusio#27346
- Loading branch information
1 parent
f1e4782
commit 4041a2d
Showing
6 changed files
with
223 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
...ests/jackson/src/main/java/io/quarkus/it/jackson/ModelWithJsonTypeIdResolverResource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package io.quarkus.it.jackson; | ||
|
||
import java.io.IOException; | ||
|
||
import javax.ws.rs.Consumes; | ||
import javax.ws.rs.GET; | ||
import javax.ws.rs.POST; | ||
import javax.ws.rs.Path; | ||
import javax.ws.rs.Produces; | ||
import javax.ws.rs.core.MediaType; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
|
||
import io.quarkus.it.jackson.model.ModelWithJsonTypeIdResolver; | ||
|
||
@Path("/typeIdResolver") | ||
public class ModelWithJsonTypeIdResolverResource { | ||
|
||
private final ObjectMapper objectMapper; | ||
|
||
public ModelWithJsonTypeIdResolverResource(ObjectMapper objectMapper) { | ||
this.objectMapper = objectMapper; | ||
} | ||
|
||
@POST | ||
@Produces(MediaType.TEXT_PLAIN) | ||
@Consumes(MediaType.APPLICATION_JSON) | ||
public String post(String body) throws IOException { | ||
ModelWithJsonTypeIdResolver input = objectMapper.readValue(body, ModelWithJsonTypeIdResolver.class); | ||
return input.getType(); | ||
} | ||
|
||
@GET | ||
@Path("one") | ||
@Produces(MediaType.APPLICATION_JSON) | ||
public String one() throws IOException { | ||
return objectMapper.writeValueAsString(new ModelWithJsonTypeIdResolver.SubclassOne()); | ||
} | ||
|
||
@GET | ||
@Path("two") | ||
@Produces(MediaType.APPLICATION_JSON) | ||
public String two() throws IOException { | ||
return objectMapper.writeValueAsString(new ModelWithJsonTypeIdResolver.SubclassTwo()); | ||
} | ||
} |
56 changes: 56 additions & 0 deletions
56
integration-tests/jackson/src/main/java/io/quarkus/it/jackson/model/CustomTypeResolver.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package io.quarkus.it.jackson.model; | ||
|
||
import com.fasterxml.jackson.annotation.JsonTypeInfo; | ||
import com.fasterxml.jackson.databind.DatabindContext; | ||
import com.fasterxml.jackson.databind.JavaType; | ||
import com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase; | ||
import com.fasterxml.jackson.databind.type.TypeFactory; | ||
|
||
public class CustomTypeResolver extends TypeIdResolverBase { | ||
|
||
private JavaType baseType; | ||
|
||
public CustomTypeResolver() { | ||
} | ||
|
||
@Override | ||
public void init(JavaType bt) { | ||
baseType = bt; | ||
} | ||
|
||
@Override | ||
public String idFromValue(Object value) { | ||
return getId(value); | ||
} | ||
|
||
@Override | ||
public String idFromValueAndType(Object value, Class<?> suggestedType) { | ||
return getId(value); | ||
} | ||
|
||
@Override | ||
public JsonTypeInfo.Id getMechanism() { | ||
return JsonTypeInfo.Id.CUSTOM; | ||
} | ||
|
||
private String getId(Object value) { | ||
if (value instanceof ModelWithJsonTypeIdResolver) { | ||
return ((ModelWithJsonTypeIdResolver) value).getType(); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
@Override | ||
public JavaType typeFromId(DatabindContext context, String id) { | ||
if (id != null) { | ||
switch (id) { | ||
case "ONE": | ||
return context.constructSpecializedType(baseType, ModelWithJsonTypeIdResolver.SubclassOne.class); | ||
case "TWO": | ||
return context.constructSpecializedType(baseType, ModelWithJsonTypeIdResolver.SubclassTwo.class); | ||
} | ||
} | ||
return TypeFactory.unknownType(); | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
...-tests/jackson/src/main/java/io/quarkus/it/jackson/model/ModelWithJsonTypeIdResolver.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package io.quarkus.it.jackson.model; | ||
|
||
import com.fasterxml.jackson.annotation.JsonIgnore; | ||
import com.fasterxml.jackson.annotation.JsonTypeInfo; | ||
import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver; | ||
|
||
@JsonTypeIdResolver(CustomTypeResolver.class) | ||
@JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM, property = "type") | ||
public abstract class ModelWithJsonTypeIdResolver { | ||
|
||
public ModelWithJsonTypeIdResolver() { | ||
} | ||
|
||
@JsonIgnore | ||
public abstract String getType(); | ||
|
||
public static class SubclassOne extends ModelWithJsonTypeIdResolver { | ||
public SubclassOne() { | ||
} | ||
|
||
@Override | ||
public String getType() { | ||
return "ONE"; | ||
} | ||
} | ||
|
||
public static class SubclassTwo extends ModelWithJsonTypeIdResolver { | ||
public SubclassTwo() { | ||
} | ||
|
||
@Override | ||
public String getType() { | ||
return "TWO"; | ||
} | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
...tion-tests/jackson/src/test/java/io/quarkus/it/jackson/ModelWithJsonTypeIdResolverIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package io.quarkus.it.jackson; | ||
|
||
import io.quarkus.test.junit.QuarkusIntegrationTest; | ||
|
||
@QuarkusIntegrationTest | ||
public class ModelWithJsonTypeIdResolverIT extends ModelWithJsonTypeIdResolverTest { | ||
|
||
// Execute the same tests but in native mode. | ||
} |
57 changes: 57 additions & 0 deletions
57
...on-tests/jackson/src/test/java/io/quarkus/it/jackson/ModelWithJsonTypeIdResolverTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package io.quarkus.it.jackson; | ||
|
||
import static io.restassured.RestAssured.given; | ||
import static org.hamcrest.CoreMatchers.equalTo; | ||
import static org.hamcrest.CoreMatchers.is; | ||
|
||
import java.io.IOException; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.Arguments; | ||
import org.junit.jupiter.params.provider.MethodSource; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
|
||
import io.quarkus.it.jackson.model.ModelWithJsonTypeIdResolver; | ||
import io.quarkus.test.junit.QuarkusTest; | ||
|
||
@QuarkusTest | ||
public class ModelWithJsonTypeIdResolverTest { | ||
|
||
static List<ModelWithJsonTypeIdResolver> typeIds() { | ||
return Arrays.asList( | ||
new ModelWithJsonTypeIdResolver.SubclassOne(), | ||
new ModelWithJsonTypeIdResolver.SubclassTwo()); | ||
} | ||
|
||
@ParameterizedTest | ||
@MethodSource("typeIds") | ||
public void testPost(ModelWithJsonTypeIdResolver instance) throws IOException { | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
|
||
given() | ||
.contentType("application/json") | ||
.body(objectMapper.writeValueAsString(instance)) | ||
.when().post("/typeIdResolver") | ||
.then() | ||
.statusCode(200) | ||
.body(is(instance.getType())); | ||
} | ||
|
||
static List<Arguments> types() { | ||
return Arrays.asList( | ||
Arguments.arguments("one", "ONE"), | ||
Arguments.arguments("two", "TWO")); | ||
} | ||
|
||
@ParameterizedTest | ||
@MethodSource("types") | ||
public void testGets(String endpoint, String expectedType) { | ||
given().when().get("/typeIdResolver/" + endpoint) | ||
.then() | ||
.statusCode(200) | ||
.body("type", equalTo(expectedType)); | ||
} | ||
} |