英文:
Deserialize String as List of Strings
问题
我有一个POJO,包含以下属性:
public class Example {
@JsonProperty("inputFoo")
private String foo;
@JsonProperty("inputBar")
private String bar;
@JsonProperty("inputBaz")
@JsonDeserialize(using = MyDeserializer.class)
private Set<String> baz;
}
我正在处理的JSON目前将baz属性表示为单个字符串:
{"inputFoo":"a", "inputBar":"b", "inputBaz":"c"}
我正在使用Jackson ObjectMapper尝试将JSON转换为我的POJO。我知道JSON中的input baz字符串无法直接映射到我尝试表示的Set,因此我定义了一个自定义的Deserializer:
public class MyDeserializer extends StdDeserializer<Set<String>> {
public MyDeserializer() {
super((Class<?>) null);
}
public Set<String> deserialize(JsonParser p, DeserializationContext cxt) throws IOException, JsonProcessingException {
String input = p.readValueAs(String.class);
Set<String> output = new HashSet<>();
if(input != null) {
output.add(input);
}
return output;
}
}
关于"inputBaz"属性,我遇到了一个IllegalArgumentException,我可以提供详细信息。有人看到我的Deserializer实现中是否有明显的问题吗?谢谢
英文:
I have a POJO that contains the following attributes
public class Example {
@JsonProperty("inputFoo")
private String foo
@JsonProperty("inputBar")
private String bar
@JsonProperty("inputBaz")
@JsonDeserialize(using = MyDeserializer.class)
private Set<String> baz
}
The JSON that I am working with to represent this data currently represents the baz attribute as a single string:
{"inputFoo":"a", "inputBar":"b", "inputBaz":"c"}
I am using the Jackson ObjectMapper to attempt to convert the JSON to my POJO. I know that the input baz String from the JSON wont map cleanly to the Set that I am trying to represent it as, so I defined a custom Deserializer:
public class MyDeserializer extends StdDeserializer<Set<String>> {
public MyDeserializer(){}
public MyDeserializer(Class<?> vc) {
super(vc);
}
public Set<String> deserialize(JsonParser p, DeserializationContext cxt) throws IOException, JsonProcessingException {
String input = p.readValueAs(String.class);
Set<String> output = new HashSet<>();
if(input != null) {
output.add(input);
}
return output;
}
}
I am getting an IllegalArgumentException referencing the "inputBaz" attribute, which I can provide details on. Does anyone see any obvious issue with my deserializer implementation? Thanks
答案1
得分: 2
不需要实现自定义反序列化器,使用ACCEPT_SINGLE_VALUE_AS_ARRAY功能。它也适用于集合:
> 该功能确定是否可以将非数组(在JSON中)的值强制转换为与Java集合(数组,java.util.Collection)类型一起使用。如果启用,集合反序列化器将尝试处理非数组值,就好像它们有一个“隐式”包围的JSON数组。此功能旨在用于兼容性/互操作性的原因,以便与在某些情况下在数组中只有单个元素的情况下,会在JSON数组中省略数组的软件包(例如XML到JSON转换器)一起使用。默认情况下,禁用此功能。
另请参阅:
英文:
You do not need to implement custom deserialiser, use ACCEPT_SINGLE_VALUE_AS_ARRAY feature. It works for sets as well:
> Feature that determines whether it is acceptable to coerce non-array
> (in JSON) values to work with Java collection (arrays,
> java.util.Collection) types. If enabled, collection deserializers will
> try to handle non-array values as if they had "implicit" surrounding
> JSON array. This feature is meant to be used for
> compatibility/interoperability reasons, to work with packages (such as
> XML-to-JSON converters) that leave out JSON array in cases where there
> is just a single element in array. Feature is disabled by default.
See also:
答案2
得分: 0
用这个无参构造函数替换掉这两个构造函数:
public MyDeserializer() {
super(TypeFactory.defaultInstance().constructCollectionType(Set.class, String.class));
}
英文:
Replace the 2 constructors with this no-arg constructor:
public MyDeserializer() {
super(TypeFactory.defaultInstance().constructCollectionType(Set.class, String.class));
}
答案3
得分: 0
ACCEPT_SINGLE_VALUE_AS_ARRAY
作为建议的选项是一个不错的选择。
也许您实际的问题更加复杂,但如果不是的话,您也可以尝试使用 @JsonCreator
替代自定义的反序列化程序。就像这样:
public class Example {
@JsonCreator
public Example(@JsonProperty("inputFoo") String foo,
@JsonProperty("inputBar") String bar,
@JsonProperty("inputBaz") String strBaz) {
this.foo = foo;
this.bar = bar;
this.baz = new HashSet<>();
baz.add(strBaz);
}
private String foo;
private String bar;
private Set<String> baz;
}
只是为了展示在更一般的情况下,您可以避免使用 @JsonCreator
来实现自定义的反序列化程序,但仍然可以进行一些简单的转换。
英文:
ACCEPT_SINGLE_VALUE_AS_ARRAY
as suggested is a good option.
Maybe your actual problem is more complicated but if not you could also try @JsonCreator
instead of custom deserializer. Like:
public class Example {
@JsonCreator
public Example(@JsonProperty("inputFoo") String foo,
@JsonProperty("inputBar") String bar,
@JsonProperty("inputBaz") String strBaz) {
this.foo = foo;
this.bar = bar;
this.baz = new HashSet<>();
baz.add(strBaz);
}
private String foo;
private String bar;
private Set<String> baz;
}
Just to show that in more general case you might avoid implementing custom deserializer with @JsonCreator
also but still make some simple conversions.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论