我可以指定jackson @JsonView用于RestEasy中的方法结果转换吗? [英] Can I specify the jackson @JsonView to use for method result transformation in RestEasy?

查看:91
本文介绍了我可以指定jackson @JsonView用于RestEasy中的方法结果转换吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用基于@JsonView的序列化模型.我通常用ContextResolver像这样配置杰克逊:

I'm working with a serialization model based on @JsonView. I normally configure jackson with a ContextResolver like this:

@Override
public ObjectMapper getContext(Class<?> aClass) {
    // enable a view by default, else Views are not processed
    Class view = Object.class;
    if (aClass.getPackage().getName().startsWith("my.company.entity")) {
        view = getViewNameForClass(aClass);
    }
    objectMapper.setSerializationConfig(
         objectMapper.getSerializationConfig().withView(view));
    return objectMapper;
}

如果我序列化单个实体,这可以很好地工作.但是,对于某些用例,我想使用与单个实体相同的视图来序列化实体列表.在这种情况下,aClassArrayList,因此通常的逻辑并没有太大帮助.

This works fine if I serialize single entities. However, for certain use cases I want to serialize lists of my entities using the same view as for single entities. In this case, aClass is ArrayList, so the usual logic doesn't help much.

所以我正在寻找一种方法来告诉杰克逊要使用哪种视图.理想情况下,我会写:

So I'm looking for a way to tell Jackson which view to use. Ideally, I'd write:

@GET @Produces("application/json; charset=UTF-8")
@JsonView(JSONEntity.class)
public List<T> getAll(@Context UriInfo uriInfo) {
    return getAll(uriInfo.getQueryParameters());
}

并在视图JSONEntity下将其序列化. RestEasy有可能吗?如果没有,我该如何模拟呢?

And have that serialized under the view JSONEntity. Is this possible with RestEasy? If not, how can I emulate that?

我知道我可以自己进行序列化:

I know I can do the serialization myself:

public String getAll(@Context UriInfo info, @Context Providers factory) {
    List<T> entities = getAll(info.getQueryParameters());
    ObjectMapper mapper = factory.getContextResolver(
         ObjectMapper.class, MediaType.APPLICATION
    ).getContext(entityClass);
    return mapper.writeValueAsString(entities);
}

但是,这充其量是笨拙的,并且破坏了使框架处理此样板的整个想法.

However, this is clumsy at best and defeats the whole idea of having the framework deal with this boilerplate.

推荐答案

结果证明, 可以简单地用@JsonView注释特定的端点(就像我的问题一样),杰克逊会使用此视图.谁会猜到的.

Turns out, it is possible to simply annotate a specific endpoint with @JsonView (just as in my question) and jackson will use this view. Who would have guessed.

您甚至可以以通用方式执行此操作(

You can even do this in the generic way (more context in my other question), but that ties me to RestEasy:

@Override
public void writeTo(Object value, Class<?> type, Type genericType, 
        Annotation[] annotations,  MediaType mediaType, 
        MultivaluedMap<String, Object> httpHd, 
        OutputStream out) throws IOException {
    Class view = getViewFromType(type, genericType);
    ObjectMapper mapper = locateMapper(type, mediaType);

    Annotation[] myAnn = Arrays.copyOf(annotations, annotations.length + 1);
    myAnn[annotations.length] = new JsonViewQualifier(view);

    super.writeTo(value, type, genericType, myAnn, mediaType, httpHd, out);
}

private Class getViewFromType(Class<?> type, Type genericType) {
    // unwrap collections
    Class target = org.jboss.resteasy.util.Types.getCollectionBaseType(
            type, genericType);
    target = target != null ? target : type;
    try {
        // use my mix-in as view class
        return Class.forName("example.jackson.JSON" + target.getSimpleName());
    } catch (ClassNotFoundException e) {
        LOGGER.info("No view found for {}", target.getSimpleName());
    }
    return Object.class;
}

这篇关于我可以指定jackson @JsonView用于RestEasy中的方法结果转换吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆