首页 > 解决方案 > 覆盖内部对象的 toString

问题描述

我已经覆盖了一个名为Skeleton的对象的 toString() ,所以当我调用 toString() 时,颜色变量被排除在外。

public class Skeleton
{
    private List bones;
    private Color color;

    //  getters & setters

    @Override
    public String toString() 
    {
        String s = null;

        ObjectMapper mapper = new ObjectMapper();
        mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector(){
        @Override
        public boolean hasIgnoreMarker(final AnnotatedMember m) {
                List<String> exclusions = Arrays.asList("color");
                return exclusions.contains(m.getName())|| super.hasIgnoreMarker(m);
            }
        });

        try 
        {
            s = mapper.writeValueAsString(this);

        } catch (JsonProcessingException e) {

            e.printStackTrace();
        }

        return s;
    }
}

但是,当我将Skeleton对象作为变量添加到名为Body的对象并在 Body 上调用 toString() 时,会包含 Skeleton 的颜色字段。

public class Body
{
    private Skeleton skeleton = ....

有谁知道如何让 Body 在 Skeleton 中使用重写的 toString() 方法?

标签: javajacksontostringobjectmapperjackson-databind

解决方案


您可以使用 Jackson注释,而不是手动排除toString方法中的字段,如果需要排除其他字段(或color不再排除),这可能会很乏味且容易出错。@JsonIgnore然后可以重写toStringin 的方法来打印序列化的字符串:Skeleton

public class Skeleton {

    private List bones;

    @JsonIgnore
    private Color color;

    @Override
    public String toString() {

        try {
            ObjectMapper mapper = new ObjectMapper();
            return mapper.writeValueAsString(this);
        } 
        catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

正如评论中提到的,如果经常使用方法,使用 anObjectMapper将对象序列化为 aString可能会很昂贵。如果性能成为问题,则应仅用于序列化最顶层的对象(即),而不是在每个中间对象(即):toStringSkeletonObjectMapperBodySkeleton

public class Skeleton {

    private List bones;

    @JsonIgnore
    private Color color;

    // Getters & setters
}

public class Body {

    private Skeleton skeleton;

    @Override
    public String toString() {

        try {
            ObjectMapper mapper = new ObjectMapper();
            return mapper.writeValueAsString(this);
        } 
        catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

根据 OP 的反馈进行编辑

如果您只想忽略特定的字段ObjectMapper,您可以创建一个SimpleBeanPropertyFilter并指定要忽略的字段的名称:

public class Skeleton {

    private List bones;
    private Color color;

    @Override
    public String toString() {

        try {
            ObjectMapper mapper = new ObjectMapper();
            FilterProvider filters = new SimpleFilterProvider()
                .addFilter("ignoreColor", SimpleBeanPropertyFilter.serializeAllExcept("color"));
            return mapper.writer(filters).writeValueAsString(this);
        } 
        catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

有关更多信息,请参阅第 5 节:使用Jackson 上的过滤器忽略字段忽略编组上的属性。


推荐阅读