杰克逊:如何动态设置属性别名

时间:2018-08-08 19:23:53

标签: java json jackson jackson2

我知道Jackson支持Mixin,我可以为以下属性设置别名:

public final class Rectangle {
    private int w;

    public Rectangle(int w) {
       this.w = w;
    }

    public int getW() { return w; }
    }
}

abstract class MixIn {
  MixIn(@JsonProperty("width") int w) { }

  @JsonProperty("width") abstract int getW();
}

然后执行以下操作:

objectMapper.addMixInAnnotations(Rectangle.class, MixIn.class);

但是我不想用注解。我想动态添加别名,例如:

objectMapper.addAlias(Rectangle.class, "w", "width")

有什么办法可以做到这一点?

注意:也可以接受excluding properties dynamically

之类的解决方案

1 个答案:

答案 0 :(得分:0)

您可以使用自定义的AnnotationIntrospector来实现,您可以在其中拦截和修改@JsonProperty的Jackson检测和使用(即使未注释字段/方法)

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.PropertyName;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;

public class DynamicPropertyAliasIntrospector extends JacksonAnnotationIntrospector
{
    @Override
    public PropertyName findNameForSerialization(Annotated a)
    {
        // if get method has @JsonProperty, return that
        PropertyName pn = super.findNameForSerialization(a);
        if (a.hasAnnotation(JsonProperty.class)) {
            return pn;
        }
        // if not annotated, value may be set dynamically 
        if (a.getName().equals("getW")) {
            // value may be set from external source as well (properties file, etc)
            pn = new PropertyName("width");
        }
        return pn;
    }
}

用法:将自定义注释内省器的实例传递给对象映射器:

public static void main(String[] args)
{
    ObjectMapper mapper = new ObjectMapper();
    mapper.setAnnotationIntrospector(new DynamicPropertyAliasIntrospector());
    Rectangle r = new Rectangle(3);
    try {
        mapper.writeValue(System.out, r);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

输出:

{"width":3}