我有Resteasy-3.0.6,Jackson-2.2.3和CDI(在Wildfly-8.0.0.CR1上运行)的设置。在我的例子中,每个实体都有一个混合类,它扩展了它并指定了要序列化的属性。有两个“视图”,我们称之为 Basic 和 Extended 。由于我需要的对象的哪种视图取决于序列化的“根”对象,因此这些视图需要是每个对象。所以我重新使用混合类。例如:
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();
}
现在我正在寻找一种方法来挂钩杰克逊的序列化过程,如果根实体是JsonJob
,则将Job
指定为视图。我目前正在使用JacksonJsonProvider#writeTo
:
@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);
}
关键是:这是有效的, iff 调用方法是注释@JsonView
。 但是由于这个主要用户是一个通用的超类,我不能直接在方法中添加注释。有人可以建议一种方法来设置现有映射器中的视图(setSerializationConfig()
似乎在jackson-2中消失)或动态地将@JsonView
添加到annotations
数组?
答案 0 :(得分:0)
以下是writeTo
现在的内容:
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延伸:
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;
}
}
请注意,这将为每个视图生成 new 编写器(应该如此)。
答案 1 :(得分:0)
使用Jackson 2.3,您可以在JAX-RS端点上使用@JsonView
,如果这样做有帮助的话。
但如果没有,另一种可能性就是直接使用ObjectWriter
(编写者是从ObjectMapper
创建的),用特定的视图构建编写器。这是完全动态的,可以在每次通话的基础上完成。这需要绕过JAX-RS逻辑,通常你需要返回StreamingOutput
(而不是实际的POJO),但这是最终的可配置性。