首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用JACKSON对JSON数据进行内联序列化的最佳方式是什么?

使用JACKSON对JSON数据进行内联序列化的最佳方式是什么?
EN

Stack Overflow用户
提问于 2012-02-13 20:47:44
回答 2查看 2.5K关注 0票数 3

我已经这样定义了一个bean:

代码语言:javascript
复制
public static class TestBean {
    private String a;
    private Long b;

    public TestBean(String a, Long b) {
        this.a = a;
        this.b = b;
    }

    public String getA() {
        return a;
    }

    public Long getB() {
        return b;
    }

}

它对一些业务进行建模,而我不需要实例化它(使用JPA)。我的一些API允许用户使用Jackson (通过JAX-RS)检索这个bean的视图,并将其序列化为JSON,我想为这个视图添加一个相关链接的列表。

通常的Jackson JSON序列化是(对于a= "aa“和b= 2L):

代码语言:javascript
复制
{"a":"aa","b":2}

我想让这些链接显示为

代码语言:javascript
复制
{"a":"aa","b":2,
 "links":[{"rel":"rel","href":"href://"},{"rel":"rel2","href":"href://2"}]}

可能的解决方法

我不希望将getLinks()方法添加到我的bean中,它特定于此视图。

简单地使用复合对象将产生类似以下的序列化:

代码语言:javascript
复制
{"data":{"a":"aa","b":2},"links":[{"rel":"rel","href":"href://"}]}

我可以接受,但这并不是我最终想要的。

当前解决方案

我希望避免操作JSON字符串或将其重新加载到Map中以插入额外的值。就目前而言,我提出的解决方案看起来非常复杂:

当前可怕的解决方案:

代码语言:javascript
复制
//a composite view object
public abstract class AddedLinksView<K> {

    private final K resource;

    private final Link[] links;

    public AddedLinksView(K resource) {
        this.resource = resource;
        links = buildLinks(resource);

    }

    public abstract Link[] buildLinks(K resource);

    public K getResource() {
        return resource;
    }

    public Link[] getLinks() {
        return links;
    }

}

//a specific bean serializer
private static class RawBeanSerializer extends BeanSerializer {

    public RawBeanSerializer(BeanSerializerBase ser) {
        super(ser);
    }

    //this is like the standard serialize but without the start and end tags
    public void rawSerialize(Object bean, JsonGenerator jgen, SerializerProvider provider) throws IOException,
            JsonGenerationException {
        if (_propertyFilterId != null) {
            serializeFieldsFiltered(bean, jgen, provider);
        } else {
            serializeFields(bean, jgen, provider);
        }
    }

}

@Test
public void usingModule() throws Exception {
    // basic module metadata just includes name and version (both for troubleshooting; but name needs to be unique)
    SimpleModule module = new SimpleModule("EnhancedDatesModule", new Version(0, 1, 0, "alpha"));
    //adding a serializer for the composite view
    module.addSerializer(new JsonSerializer<AddedLinksView>() {

        @Override
        public Class<AddedLinksView> handledType() {
            return AddedLinksView.class;
        }

        @Override
        public void serialize(AddedLinksView value, JsonGenerator jgen, SerializerProvider provider)
                throws IOException, JsonProcessingException {
            jgen.writeStartObject();
            //looking up the bean serializer that will be used for my resource
            JsonSerializer<Object> ser = provider.findTypedValueSerializer(value.getResource().getClass(), true,
                    null);

            if (ser instanceof BeanSerializerBase) {
                //cloning it in a sub class that makes it possible to 'inline' the serialization
                RawBeanSerializer openSer = new RawBeanSerializer((BeanSerializerBase) ser);
                openSer.rawSerialize(value.getResource(), jgen, provider);
            }
            //adding my links
            jgen.writeArrayFieldStart("links");
            for (Link link : value.getLinks()) {
                jgen.writeObject(link);
            }
            jgen.writeEndArray();
            jgen.writeEndObject();
        }

    });

    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(module);

    AddedLinksView<TestBean> view = new AddedLinksView<TestBean>(new TestBean("aa", 2L)) {
        @Override
        public Link[] buildLinks(TestBean resource) {
            return new Link[] { new Link("rel", "href://"), new Link("rel2", "href://2") };
        }

    };

    System.out.println("useModule json output: " + mapper.writeValueAsString(view));
}

我是不是错过了杰克逊身上的一些显而易见的东西来实现这一点?或者我的需求已经完全偏离目标了吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-14 06:48:21

没有真正的方法可以从外部将内容注入POJO进行序列化:但是您可能有兴趣查看@JsonAnyGetter,它至少允许将java.util.Map的内容作为POJO的额外属性添加。

票数 3
EN

Stack Overflow用户

发布于 2012-02-13 21:55:52

这能回答你的问题吗:http://wiki.fasterxml.com/JacksonFeatureUpdateValue

我不确定您是否可以避免映射。你可以使用Dozer来帮助你。

这应该会对你有所帮助:Tools for merging java beans

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9260800

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档