使用Dropwizard定制序列化器/反序列化器的选项?

时间:2015-02-26 19:33:47

标签: jersey jackson dropwizard jersey-client

使用dropwizard在外部注册自定义(反)序列化程序的好方法是什么?

我遇到了(de)序列化复合对象的问题。我尝试使用@JsonUnwrapped来获取我想要的JSON,但是在反序列化方面遇到了问题 - 它需要特殊的构造函数来获取字符串并要求复合对象具有构造封装对象的知识。此外,我想要一种不必在我的价值对象上使用杰克逊注释的方法。

例如,我有:

public class SubmissionModule extends SimpleModule {
    public SubmissionModule() {
        addDeserializer(SubmissionDetails.class, new SubmissionDeserializer());
        addSerializer(SubmissionDetails.class, new SubmissionSerializer());
    }

    public class SubmissionSerializer extends JsonSerializer<SubmissionDetails> {
        @Override
        public void serialize(SubmissionDetails value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
            jgen.writeStartObject();
            jgen.writeStringField("id", "" + value.getId());
            jgen.writeStringField("title", value.getTitle());
            jgen.writeStringField("abstract", value.getAbstract());
            jgen.writeEndObject();
        }
    }

    public class SubmissionDeserializer extends JsonDeserializer<SubmissionDetails> {
        @Override
        public SubmissionDetails deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException {
            JsonNode node = jp.getCodec().readTree(jp);
            return aSubmissionWithId(SubmissionId.from(node.get("id").asText()))
                    .title(node.get("title").asText())
                    .abstract_(node.get("abstract").asText()).create();
        }
    }
}

我已经在DropWizard中注册了,如下所示: bootstrap.getObjectMapper().registerModule(new SubmissionModule());

但我无法弄清楚是否可以使用Jersey客户端(或使用ResourceTestRule时可用的客户端)注册(de)序列化程序。

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

  

“但我无法弄清楚是否可以使用Jersey客户端(或使用ResourceTestRule时可用的客户端)注册(de)序列化程序。”

查看source code for ResourceTestRule。有一种方法setMapper(ObjectMapper)

您可以执行类似

的操作
ObjectMapper mapper = Jackson.newObjectMapper();
mapper.registerModule(new SubmissionModule());
@ClassRule
public static final ResourceTestRule RULE 
           = new ResourceTestRule.Builder().setMapper(mapper).addResource(...).build();

答案 1 :(得分:1)

我不知道您在@JsonUnwrapped上获取信息的位置,但它不需要包含和封装对象之间的特殊构造函数或依赖项。否则它不会真正增加很多用途。 注释仅表示所引用的Object应该写为属性序列(在父对象中),而不是Object值。 不是说它一定适用于你的用例,但你可能已经看到了不好的示例代码或其他东西。

关于避免值对象中的注释:一种方法是使用&#34;混合注释&#34; (http://www.studytrails.com/java/json/java-jackson-mix-in-annotation.jsp)。 有了它,您可以使用@JsonSerialize(using=MySerializer.class)@JsonDeserialize(using=MyDeserializer.class)来指示要使用的处理程序。

注册自定义(反)序列化程序是通过实现Module(通常只是构造或子类SimpleModule)并使用DropWizard使用的ObjectMapper注册它来处理的。