Gil*_*ili 80 java json jersey jackson
我希望Jackson使用以下构造函数反序列化一个类:
public Clinic(String name, Address address)
Run Code Online (Sandbox Code Playgroud)
反序列化第一个参数很容易.问题是地址被定义为:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
并构造如下: new Address.Builder().setCity("foo").setCountry("bar").create();
有没有办法从杰克逊获得键值对,以便自己构建地址?或者,有没有办法让杰克逊使用Builder类本身?
Rup*_*ott 127
只要您使用的是Jackson 2+,那么现在就可以为此提供支持.
首先,您需要将此注释添加到您的Address类:
@JsonDeserialize(builder = Address.Builder.class)
Run Code Online (Sandbox Code Playgroud)
然后,您需要将此注释添加到您的Builder类:
@JsonPOJOBuilder(buildMethodName = "create", withPrefix = "set")
Run Code Online (Sandbox Code Playgroud)
如果您乐意将Builder的create方法重命名为build,并且Builder的setter前缀为with而不是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();
}
}
Run Code Online (Sandbox Code Playgroud)
vol*_*var 20
@Rupert Madden-Abbott的答案很有效.但是,如果你有一个非默认的构造函数,例如,
Builder(String city, String country) {...}
Run Code Online (Sandbox Code Playgroud)
然后你应该注释如下参数:
@JsonCreator
Builder(@JsonProperty("city") String city,
@JsonProperty("country") String country) {...}
Run Code Online (Sandbox Code Playgroud)
我最终使用@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();
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
在这种情况下适合我的解决方案(我使用了“ Lombok”构建器注释)。
@Getter
@Builder(builderMethodName = "builder")
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@JsonAutoDetect(
fieldVisibility = JsonAutoDetect.Visibility.ANY,
creatorVisibility = JsonAutoDetect.Visibility.ANY
)
Run Code Online (Sandbox Code Playgroud)
我希望对您也有用。
| 归档时间: |
|
| 查看次数: |
42817 次 |
| 最近记录: |