Skip to content

Commit

Permalink
Merge pull request #11635 from gsmet/json-naming-native
Browse files Browse the repository at this point in the history
Register Jackson @JsonNaming strategies for reflection
  • Loading branch information
gsmet authored Aug 26, 2020
2 parents b16296e + 7800adb commit 09496dd
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public class JacksonProcessor {
private static final DotName JSON_DESERIALIZE = DotName.createSimple(JsonDeserialize.class.getName());
private static final DotName JSON_SERIALIZE = DotName.createSimple(JsonSerialize.class.getName());
private static final DotName JSON_CREATOR = DotName.createSimple("com.fasterxml.jackson.annotation.JsonCreator");
private static final DotName JSON_NAMING = DotName.createSimple("com.fasterxml.jackson.databind.annotation.JsonNaming");
private static final DotName BUILDER_VOID = DotName.createSimple(Void.class.getName());

private static final String TIME_MODULE = "com.fasterxml.jackson.datatype.jsr310.JavaTimeModule";
Expand Down Expand Up @@ -117,7 +118,7 @@ CapabilityBuildItem register() {
AnnotationValue usingValue = deserializeInstance.value("using");
if (usingValue != null) {
// the Deserializers are constructed internally by Jackson using a no-args constructor
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, usingValue.asClass().toString()));
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, usingValue.asClass().name().toString()));
}
}

Expand All @@ -128,7 +129,7 @@ CapabilityBuildItem register() {
AnnotationValue usingValue = serializeInstance.value("using");
if (usingValue != null) {
// the Deserializers are constructed internally by Jackson using a no-args constructor
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, usingValue.asClass().toString()));
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, usingValue.asClass().name().toString()));
}
}
}
Expand All @@ -140,6 +141,14 @@ CapabilityBuildItem register() {
}
}

// register @JsonNaming strategy implementations for reflection
for (AnnotationInstance jsonNamingInstance : index.getAnnotations(JSON_NAMING)) {
AnnotationValue strategyValue = jsonNamingInstance.value("value");
if (strategyValue != null) {
reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, strategyValue.asClass().name().toString()));
}
}

// this needs to be registered manually since the runtime module is not indexed by Jandex
additionalBeans.produce(new AdditionalBeanBuildItem(ObjectMapperProducer.class));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.quarkus.it.jackson;

import java.io.IOException;

import javax.ws.rs.GET;
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.SampleResponse;

@Path("/json-naming/")
public class ModelWithJsonNamingStrategyResource {

private final ObjectMapper objectMapper;

public ModelWithJsonNamingStrategyResource(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}

@GET
@Produces(MediaType.APPLICATION_JSON)
public String get() throws IOException {
return objectMapper.writeValueAsString(new SampleResponse("My blog post"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.quarkus.it.jackson.model;

import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;

import io.quarkus.runtime.annotations.RegisterForReflection;

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
@RegisterForReflection
public class SampleResponse {

private String blogTitle;

public SampleResponse() {
}

public SampleResponse(String blogTitle) {
this.blogTitle = blogTitle;
}

public String getBlogTitle() {
return blogTitle;
}

public void setBlogTitle(String blogTitle) {
this.blogTitle = blogTitle;
}

@Override
public String toString() {
return "SampleResponse{" +
"blogTitle='" + blogTitle + '\'' +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.quarkus.it.jackson;

import io.quarkus.test.junit.NativeImageTest;

@NativeImageTest
public class ModelWithJsonNamingStrategyResourceIT extends ModelWithJsonNamingStrategyResourceTest {

// Execute the same tests but in native mode.
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.quarkus.it.jackson;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.containsString;

import java.io.IOException;

import org.junit.jupiter.api.Test;

import io.quarkus.test.junit.QuarkusTest;

@QuarkusTest
public class ModelWithJsonNamingStrategyResourceTest {

@Test
public void testStrategy() throws IOException {
given()
.when().get("/json-naming/")
.then()
.statusCode(200)
.body(containsString("blog_title"));
}

}

0 comments on commit 09496dd

Please sign in to comment.