I have a custom annotation to processing JSON:
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface Filtered {
FilterType filterType() default FilterType.ALL;
}
with custom object mapper:
@Component
public class FilteredObjectMapper extends ObjectMapper {
public FilteredObjectMapper() {
registerModule(new JavaTimeModule());
setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
@Override
public Object findSerializer(Annotated a) {
Filtered annotation = a.getAnnotation(Filtered.class);
if (annotation != null) {
return new FilteredSerializer(annotation.filterType());
}
return super.findSerializer(a);
}
});
}
}
and Serializer
public class FilteredSerializer extends StdSerializer<String> {
private final FilterType type;
private static final String FILTERED = "FILTERED";
public FilteredSerializer(FilterType ft) {
super(String.class);
this.type = ft;
}
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider provider) throws IOException {
if (value == null) {
gen.writeNull();
}
switch (type) {
case EMAIL -> gen.writeString(StringTool.maskEmail(value));
case ALL -> gen.writeString(FILTERED);
}
}
}
Finally i have test for this:
record TestRecord(@Filtered(filterType = FilterType.EMAIL) String str1, @Filtered(filterType = FilterType.ALL) String str2) {}
class FilteredObjectMapperTest {
@Test
void fiteringTest() throws JsonProcessingException {
FilteredObjectMapper filteredObjectMapper = new FilteredObjectMapper();
ObjectMapper om = new ObjectMapper();
TestRecord baseRecord = new TestRecord("test@somedomain.com", "Text to remove");
String str = filteredObjectMapper.writeValueAsString(baseRecord);
TestRecord deserializedRecord = om.readValue(str, TestRecord.class);
Assertions.assertNotEquals(deserializedRecord.str1(), baseRecord.str1());
Assertions.assertNotEquals(deserializedRecord.str2(), baseRecord.str2());
Assertions.assertEquals("FILTERED", deserializedRecord.str2());
}
}
This solution work perfectly in Spring boot 3.2.x but in 3.3.x is failing, deserializedRecord.str1 and baseRecord.str1 are equal
after downgrade jackson to 2.15 is ok, maybe is another solution?
dependencyManagement {
imports {
mavenBom 'com.fasterxml.jackson:jackson-bom:2.15.5'
}
}
Comment From: wilkinsona
after downgrade jackson to 2.15 is ok
Given that your test does not appear to rely on Spring Boot and that it works with an older version of Jackson, this appears to be a regression in Jackson. Please open a Jackson issue so that it can be investigated. We'll pick up any new version of Jackson that fixes the problem in due course.
Comment From: Grzegorz-Zarnowiecki
Jackson 2.18 is ok, so please update this dependency :) For this moment have 3 solutions: 1. downgrade jackson to 2.15 2. upgrade jackson to 2.18 3. In FilteredObjectMapper add:
setVisibility(new VisibilityChecker.Std(JsonAutoDetect.Visibility.ANY))
Comment From: wilkinsona
2.18 has not yet been released. At the time of writing, 2.17.1 is the latest available version and Spring Boot 3.3 is already using it.
Comment From: Grzegorz-Zarnowiecki
... Yes, I know, but version 2.18 is coming... Jackson issue