首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当重写JacksonJsonProvider.writeTo时,我可以指定用于序列化的视图吗?

当重写JacksonJsonProvider.writeTo时,我可以指定用于序列化的视图吗?
EN

Stack Overflow用户
提问于 2014-01-21 08:45:24
回答 2查看 1.2K关注 0票数 1

我已经安装了Resteasy-3.0.6,Jackson-2.2.3和CDI (运行在Wildfli-8.0.0.CR1上)。在我的例子中,每个实体都有一个混合类来扩展它,并指定要序列化的属性。有两个“视图”,我们称它们为基本视图和扩展视图。因为我需要对象的哪种视图取决于序列化的“根”对象,所以这些视图需要针对每个对象。所以我重复使用混合类。示例:

代码语言:javascript
复制
public class Job { 
    @Id private Long id;
    @OneToMany(mappedBy="job") private Set<Bonus> bonuses;
}

public class Bonus {
    @Id private Long id;
    @ManyToOne(optional=false) private Job job;
    private BigDecimal value;
}

public abstract class JsonJob extends Job { 
    abstract Long getId();

    @JsonView({ JsonJob.class })
    abstract Set<Bonus> getBonuses();
}

public abstract class JsonBonus extends Bonus {
    abstract BigDecimal getValue();
}

现在,我正在寻找一种方法来连接到jackson的序列化过程,将JsonJob指定为视图,如果根实体是Job的话。我目前正在使用JacksonJsonProvider#writeTo

代码语言:javascript
复制
@Override
public void writeTo(Object value, Class<?> type, Type genericType, 
                    Annotation[] annotations, MediaType mediaType, 
                    MultivaluedMap<String, Object> httpHeaders, 
                    OutputStream entityStream) throws IOException {
    Class view = getViewForType(type); // if no mix-in class is set, return Object
    ObjectMapper mapper = locateMapper(type, mediaType);

    // require all properties to be explicitly specified for serialization
    mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
    mapper.registerModule(new SerializationMixinConf()); // registers all mix-ins

    super.writeTo(value, type, genericType, annotations, mediaType, 
        httpHeaders, entityStream);
}

关键是:这是可行的,当且仅当调用方法是带注释的@JsonView但是,因为它的主要用户是一个泛型超类,所以我不能直接将注释添加到方法中。有人能建议一种方法来设置现有映射器中的视图(setSerializationConfig()似乎在Jackson-2中消失了),或者动态地将@JsonView添加到annotations数组中吗?

EN

回答 2

Stack Overflow用户

发布于 2014-01-21 15:20:00

下面是我现在在writeTo中的内容:

代码语言:javascript
复制
ObjectMapper mapper = locateMapper(type, mediaType);
// require all properties to be explicitly specified for serialization
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
mapper.registerModule(new SerializationMixinConf());

// TODO: check if we already have @JsonView
Annotation[] myAnnotations = Arrays.copyOf(annotations, annotations.length + 1);
myAnnotations[annotations.length] = new JsonViewQualifier(view);

super.writeTo(value, type, genericType, myAnnotations, mediaType, 
    httpHeaders, entityStream);

而限定符只是从AnnotationLiteral扩展而来。

代码语言:javascript
复制
public class JsonViewQualifier extends AnnotationLiteral<JsonView> 
        implements JsonView {
    private final Class[] views;

    public JsonViewQualifier(Class[] views) { this.views = views; }
    public JsonViewQualifier(Class view) { this(new Class[] { view }); }

    @Override
    public Class<?>[] value() {
        return views;
    }
}

请注意,这将为每个视图生成一个新的编写器(正如它应该的那样)。

票数 0
EN

Stack Overflow用户

发布于 2014-01-21 18:19:33

使用Jackson2.3,您可以在JAX端点上使用@JsonView,如果这有帮助的话。

但如果不是,另一种可能是直接使用ObjectWriter (作者是从ObjectMapper创建的),用特定的视图构造编写器。这是完全动态的,可以按要求进行。这需要通过JAX-RS逻辑实现,通常需要返回StreamingOutput (而不是实际的POJO),但它在可配置性方面是终极的。

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

https://stackoverflow.com/questions/21253114

复制
相关文章

相似问题

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