字段的特定MessageBodyWriter [英] Specific MessageBodyWriter for field
问题描述
假设我在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 $来实现c $ c>用于
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屋!