Skip to content

Commit

Permalink
fix: micronaut-projects#233 Allow @JsonIgnoreProperties and @JsonUnwr…
Browse files Browse the repository at this point in the history
…apped to work together
  • Loading branch information
edeesis committed Jul 6, 2022
1 parent 56e6343 commit eb5cceb
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class Name {
this.first = first;
}
public String getFirst() {
return first;
return first;
}
}
""")
Expand Down Expand Up @@ -153,6 +153,102 @@ class Name {
context.close()
}

void "test @JsonUnwrapped with @JsonIgnoreProperties"() {
given:
def context = buildContext("""
package unwrapped;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import io.micronaut.core.annotation.Introspected;
import io.micronaut.serde.annotation.Serdeable;
@Serdeable
@Introspected(accessKind = Introspected.AccessKind.FIELD)
class Parent {
public int age;
@JsonUnwrapped
@JsonIgnoreProperties("ignored")
public Name name;
}
@Serdeable
@Introspected(accessKind = Introspected.AccessKind.FIELD)
class Name {
public String first, last;
public String ignored;
}
""")

when:
def name = newInstance(context, 'unwrapped.Name', [first:"Fred", last:"Flinstone", ignored:"Ignored"])
def parent = newInstance(context, 'unwrapped.Parent', [age:10, name:name])

def result = writeJson(jsonMapper, parent)

then:
result == '{"age":10,"first":"Fred","last":"Flinstone"}'

when:
def read = jsonMapper.readValue(result, Argument.of(context.classLoader.loadClass('unwrapped.Parent')))

then:
read.age == 10
read.name.first == 'Fred'
read.name.last == "Flinstone"

cleanup:
context.close()
}

void "test @JsonUnwrapped with @JsonIgnoreProperties on class"() {
given:
def context = buildContext("""
package unwrapped;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import io.micronaut.core.annotation.Introspected;
import io.micronaut.serde.annotation.Serdeable;
@Serdeable
@Introspected(accessKind = Introspected.AccessKind.FIELD)
class Parent {
public int age;
@JsonUnwrapped
public Name name;
}
@Serdeable
@Introspected(accessKind = Introspected.AccessKind.FIELD)
@JsonIgnoreProperties("ignored")
class Name {
public String first, last;
public String ignored;
}
""")

when:
def name = newInstance(context, 'unwrapped.Name', [first:"Fred", last:"Flinstone", ignored:"Ignored"])
def parent = newInstance(context, 'unwrapped.Parent', [age:10, name:name])

def result = writeJson(jsonMapper, parent)

then:
result == '{"age":10,"first":"Fred","last":"Flinstone"}'

when:
def read = jsonMapper.readValue(result, Argument.of(context.classLoader.loadClass('unwrapped.Parent')))

then:
read.age == 10
read.name.first == 'Fred'
read.name.last == "Flinstone"

cleanup:
context.close()
}

@Requires({ jvm.isJava17Compatible() })
void "test @JsonUnwrapped records"() {
given:
Expand Down Expand Up @@ -355,7 +451,7 @@ class Parent {
public final int age;
@JsonUnwrapped
public final Name name;
Parent(int age, @JsonUnwrapped Name name) {
this.age = age;
this.name = name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,24 +212,29 @@ public void initialize(Serializer.EncoderContext context) {
PropertyNamingStrategy propertyNamingStrategy = getPropertyNamingStrategy(property.getAnnotationMetadata(), encoderContext, entityPropertyNamingStrategy);
if (unwrapped) {
BeanIntrospection<Object> propertyIntrospection = introspections.getSerializableIntrospection(property.asArgument());
Set<String> ignoredProperties = Arrays.stream(argument.getAnnotationMetadata().stringValues(SerdeConfig.SerIgnored.class)).collect(Collectors.toSet());
for (BeanProperty<Object, Object> unwrappedProperty : propertyIntrospection.getBeanProperties()) {
Argument<Object> unwrappedPropertyArgument = unwrappedProperty.asArgument();
String n = resolveName(propertyAnnotationMetadata,
if (!ignoredProperties.contains(unwrappedProperty.getName())) {
Argument<Object> unwrappedPropertyArgument = unwrappedProperty.asArgument();
String n = resolveName(propertyAnnotationMetadata,
unwrappedProperty.getAnnotationMetadata(),
unwrappedPropertyArgument.getName(),
true, propertyNamingStrategy);
final AnnotationMetadataHierarchy combinedMetadata =
final AnnotationMetadataHierarchy combinedMetadata =
new AnnotationMetadataHierarchy(
argument.getAnnotationMetadata(),
unwrappedProperty.getAnnotationMetadata()
argument.getAnnotationMetadata(),
unwrappedProperty.getAnnotationMetadata()
);
CustomSerProperty<T, Object> prop = new CustomSerProperty<>(SerBean.this, n,
unwrappedPropertyArgument,
combinedMetadata,
bean -> unwrappedProperty.get(property.get(bean))
);
writeProperties.add(prop);
initializers.add(ctx -> initProperty(prop, ctx));
if (!combinedMetadata.booleanValue(SerdeConfig.class, SerdeConfig.IGNORED).orElse(false)) {
CustomSerProperty<T, Object> prop = new CustomSerProperty<>(SerBean.this, n,
unwrappedPropertyArgument,
combinedMetadata,
bean -> unwrappedProperty.get(property.get(bean))
);
writeProperties.add(prop);
initializers.add(ctx -> initProperty(prop, ctx));
}
}
}
} else {
String n = resolveName(annotationMetadata, propertyAnnotationMetadata, defaultPropertyName, false, propertyNamingStrategy);
Expand Down

0 comments on commit eb5cceb

Please sign in to comment.