字段的特定MessageBodyWriter [英] Specific MessageBodyWriter for field

查看:97
本文介绍了字段的特定MessageBodyWriter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我在JAX-RS 1环境中有数据类(与Jackson提供商一起使用RestEasy 2),如下所示:

Say I have a data class in a JAX-RS 1 environment (RestEasy 2 with the Jackson provider) like this:

class Foo {
   int id;
   String name;
   Bar bar;

   ...
}

Bar 正在:

class Bar {
   int one;
   String two;
}

现在我想要 Bar 以特殊方式序列化(可能取决于所请求的媒体类型(或取决于月亮的相位),我会写一个 MessageBodyWriter< Bar>

Now I want to have Bar serialized in a special way (perhaps depending on the media type that was requested (or depending the phase of the moon), I would write a MessageBodyWriter<Bar>

@Provider
@Produces("application/json")
public class BarWriter implements MessageBodyWriter<Bar> {
   ...
}

如果<$ c,效果非常好$ c> Bar 是单独请求的

@GET @Path("bar")  
public Bar getBar() { return new Bar(...); }

但是当我请求 Foo 时,如

@GET @Path("foo")  
public Foo getFoo() { return new Foo(...); }

邮件正文编写器被忽略。

the message body writer is ignored.

现在我想要的是这个 MessageBodyWriter 也用于我返回 Foo 列表< Bar>

Now what I want is that this MessageBodyWriter is also used when I return Foo or a List<Bar>

我认为后者可以通过编写自定义 MessageBodyWriter 用于 List 的情况,但对于前一种情况,我无法为包含的所有应用程序类编写消息正文编写器栏字段。

I think the latter can be achieved by just writing a custom MessageBodyWriter for the List case, but for the former case I can't write a message body writer for all my application classes that contain a Bar field.

有关如何解决此问题的任何想法?我还试图在 Bar 实例上使用Jackson序列化程序,但看起来这甚至没有被RestEasy注册(然后,我认为这样的方式太脆弱了)。

Any ideas on how to solve this? I was also trying to use a Jackson serializer on the Bar instance, but it looks like this is not even registered by RestEasy (and then, I think that way is too fragile anyway).

推荐答案

不幸的是,这不是邮件正文编写者的工作方式。 JAX-RS实现将根据资源方法返回的类型定位要在序列化中使用的编写器。因此,在您的情况下,使用此资源方法为 Bar 定义自定义编写器:

Unfortunately, this is not how message body writers work. The JAX-RS implementation will locate a writer, to be used in serialization, based on the type being returned from your resource method. So in your case, with a custom writer defined for Bar, with this resource method:

@GET @Path("bar")  
public Bar getBar() { return new Bar(...); }

JAX-RS提供程序将序列化 Bar 使用自定义编写器。但是对于此资源方法:

the JAX-RS provider will serialize Bar using your custom writer. However for this resource method:

@GET @Path("foo")  
public Foo getFoo() { return new Foo(...); }

您没有定义自定义编写器,序列化将由第一个匹配处理(默认)可以处理返回类和内容类型组合的提供者。需要记住的一件事是,与典型的JSON和XML序列化库不同,JAX-RS实体提供程序 是递归的。 Aka,对于在资源方法中返回的给定对象 A ,提供程序将尝试为 > A ,而不是 A 中包含的任何类型作为变量。

you do not have a custom writer defined, and serialization will be handled by the first matching (default) provider that can handle the combination of return class and content-type. A key thing to remember is that, unlike typical JSON and XML serialization libraries, JAX-RS entity providers are not recursive. Aka, for a given object A being returned in a resource method, the provider will attempt to locate a custom writer only for A, and not for any of the types included in A as variables.

既然你使用Jackson,为什么不为你的 Bar 类定义一个自定义序列化器呢?这将处理您描述的几乎所有情况:

Since you are using Jackson though, why not just define a custom serializer for your Bar class? That will handle pretty much every scenario you described:

public class BarSerializer extends JsonSerializer<Bar> {

    @Override
    public void serialize(final Bar value, final JsonGenerator jgen,
            final SerializerProvider provider) throws IOException,
            JsonProcessingException {

        jgen.writeStartObject();
        jgen.writeFieldName("myBar");
        jgen.writeString(value.getTwo());
        jgen.writeEndObject();
    }
}

你告诉Jackson这样使用这个自定义序列化器: / p>

You tell Jackson to use this custom serializer thusly:

@JsonSerialize(using=BarSerializer.class)
class Bar {
   int one;
   String two;
}

最后,不要忘记,如果你期望让JSON重新回归在您序列化时,您还需要一个自定义 JsonDeserializer

Lastly, don't forget that if you anticipate getting JSON back in the same form as you serialized, that you will also need a custom JsonDeserializer.

要使其正常工作,您需要 jackson-mapper jackson-jaxrs 你的类路径中的jars(可能还有 jackson-core 一个)。

To get it to work, you need the jackson-mapper and jackson-jaxrs jars in your classpath (and probably the jackson-core one as well).

这篇关于字段的特定MessageBodyWriter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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