5

に基づくシリアル化モデルを使用してい@JsonViewます。私は通常、次のようにjacksonを設定しますContextResolver

@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;
}

単一のエンティティをシリアル化すると、これはうまく機能します。ただし、特定のユース ケースでは、単一のエンティティと同じビューを使用して、エンティティのリストをシリアル化したいと考えています。この場合、aClassisArrayListであるため、通常のロジックはあまり役に立ちません。

そこで、Jackson にどのビューを使用するかを伝える方法を探しています。理想的には、次のように書きます。

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

そして、それをビューの下でシリアル化しますJSONEntity。これは RestEasy で可能ですか? そうでない場合、どうすればそれをエミュレートできますか?

編集:私は自分でシリアル化を行うことができることを知っています:

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);
}

ただし、これはせいぜい不器用であり、フレームワークにこのボイラープレートを処理させるという考え全体を無効にします。

4

1 に答える 1

6

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;
}
于 2014-01-22T21:37:10.060 に答える