jackson+生成器模式?
我希望Jackson用下面的构造函数反序列化一个类:
public Clinic(String name, Address address)
反序列化第一个参数很容易。 问题是,地址被定义为:
public class Address { private Address(Map<LocationType, String> components) ... public static class Builder { public Builder setCity(String value); public Builder setCountry(String value); public Address create(); } }
并构造如下: new Address.Builder().setCity("foo").setCountry("bar").create();
有没有办法让jackson的键值对自己构build地址? 另外,有没有办法让jackson使用Builder类本身?
只要你使用jackson2+,那么现在就build立在支持这个 。
首先,您需要将此注释添加到Address
类中:
@JsonDeserialize(builder = Address.Builder.class)
然后你需要把这个注释添加到你的Builder
类中:
@JsonPOJOBuilder(buildMethodName = "create", withPrefix = "set")
如果你很高兴重新命名你的Builder的create方法,你可以跳过这第二个注释,而你的Builder的setter可以用set而不是set作为前缀。
完整的例子:
@JsonDeserialize(builder = Address.Builder.class) public class Address { private Address(Map<LocationType, String> components) ... @JsonPOJOBuilder(buildMethodName = "create", withPrefix = "set") public static class Builder { public Builder setCity(String value); public Builder setCountry(String value); public Address create(); } }
@Rupert Madden-Abbott的答案是有效的。 但是,如果你有一个非默认的构造函数,例如,
Builder(String city, String country) {...}
那么你应该注释参数如下:
@JsonCreator Builder(@JsonProperty("city") String city, @JsonProperty("country") String country) {...}
我结束了实现这个使用@JsonDeserialize如下:
@JsonDeserialize(using = JacksonDeserializer.class) public class Address {...} @JsonCachable static class JacksonDeserializer extends JsonDeserializer<Address> { @Override public Address deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException { JsonToken token = parser.getCurrentToken(); if (token != JsonToken.START_OBJECT) { throw new JsonMappingException("Expected START_OBJECT: " + token, parser.getCurrentLocation()); } token = parser.nextToken(); Builder result = new Builder(); while (token != JsonToken.END_OBJECT) { if (token != JsonToken.FIELD_NAME) { throw new JsonMappingException("Expected FIELD_NAME: " + token, parser.getCurrentLocation()); } LocationType key = LocationType.valueOf(parser.getText()); token = parser.nextToken(); if (token != JsonToken.VALUE_STRING) { throw new JsonMappingException("Expected VALUE_STRING: " + token, parser.getCurrentLocation()); } String value = parser.getText(); // Our Builder allows passing key-value pairs // alongside the normal setter methods. result.put(key, value); token = parser.nextToken(); } return result.create(); } }
目前还没有支持生成器模式的支持,尽pipe它已经被要求了一段时间(最后提交了Jira issue http://jira.codehaus.org/browse/JACKSON-469 ) – 这是可以添加的东西如果有足够的需求,请发布1.8版本(请务必在Jira投票!)。 这是一个合理的附加function,只能延迟开发人员的时间。 但我认为这将是很好的补充。