RFE: global or class level support for fields prefix
See original GitHub issueIn some code guidlines, fields are required to have some prefix(e.g. the “m” in AOSP and the underscores in jackson souce codes and we developers are required to follow these ), so our data class will look like these
public class User {
private Long mId;
public void getId() {
return mId;
}
public void setId(Long id) {
mId = id;
}
}
At this case, the mId
field must be annotated by the JsonProperty("id")
, if not , jackson will recognize mId
and id
as two properties. That’s ok if we have few fields or few classes. But it really pains when we have to mark all fields in all class those have the prefix. After searching documents, I found there is a workaround – insert a AnnotationIntrospector
by registering a custom module(some hardcode here)
class PrefixIntrospector extends JacksonAnnotationIntrospector {
private static final Pattern M = Pattern.compile("\\bm([A-Z]).*");
private static String doTrans(Annotated a) {
if (!(a instanceof AnnotatedField)) {
return null;
}
AnnotatedField f = (AnnotatedField) a;
String name = f.getName();
Matcher matcher = M.matcher(name);
if (matcher.find()) {
String start = matcher.group(1).toLowerCase();
if (name.length() > 2) {
return start + name.substring(2);
}
return start;
}
return null;
}
@Override
public String findImplicitPropertyName(final AnnotatedMember m) {
String parent = super.findImplicitPropertyName(m);
if (parent != null) {
return parent;
}
return doTrans(m);
}
@Override
public PropertyName findNameForDeserialization(final Annotated a) {
PropertyName parent = super.findNameForDeserialization(a);
if (parent != null) {
return parent;
}
String newName = doTrans(a);
return newName == null ? null : PropertyName.construct(newName);
}
@Override
public PropertyName findNameForSerialization(final Annotated a) {
PropertyName parent = super.findNameForSerialization(a);
if (parent != null) {
return parent;
}
String newName = doTrans(a);
return newName == null ? null : PropertyName.construct(newName);
}
}
That works for me, but let’s go further, could there be a global config or class level annotation for this case? Maybe an annotation like these:
// a global config
public ObjectMapper newMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(FIELDS_PREFIX, "m");
return mapper;
}
// or class level annotation
@FiledsStyle(prefix="m")
public class User {
private Long mId;
private String mName;
// omits getters and setters
}
If there is a feature already here and I didn’t find, I am sorry for wasting your time. At last, thanks for reading
Issue Analytics
- State:
- Created 5 years ago
- Comments:7 (3 by maintainers)
Top GitHub Comments
If you want the
PROPAGATE_TRANSIENT_MARKER
to work, the workaround presented in this solution is incorrect. You really only need to override thefindImplicitPropertyName
as if you return anything but null from the other two the code thinks you have an actual annotation, and ignores thetransient
keyword.No plans to tackle this, closing.