Reputation: 11920
I am trying to deserialize YAML map to Java Map of simple String keys and values for these cases:
myMap:
key: value
myMap:
# key: value
Here's the Java Pojo to create after deserialization:
class Config {
@JsonProperty Map<String, String> myMap;
public Config() {}
public Config(Map<String, String> myMap) { this.myMap = myMap; }
public Map<String, String> getMyMap() { return myMap; }
@Override
public String toString() {
return "Config{" + "map=" + myMap + '}';
}
}
And the main is :
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
String yaml = ".."
Config config = mapper.readValue(yaml, Config.class);
System.out.println(config);
}
The project uses these dependencies:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>2.1.4</version>
</dependency>
In case of yaml = "myMap:\n" + " key: somevalue"
, the deserialization works fine, and we can see Config{myMap={key=somevalue}}
In case of yaml = "myMap:\n" + "";
(empty or commented entries), Jackson logs these errors:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [map type; class java.util.LinkedHashMap, [simple type, class java.lang.String] -> [simple type, class java.lang.String]] from String value; no single-String constructor/factory method (through reference chain: com.example.Config["myMap"]) ...
How can I do to manage the case where the lines are commented or there are no provided key/value pairs?
Upvotes: 1
Views: 808
Reputation: 39768
A YAML block-style map, like the one you use, is implicitly started with the first key/value pair. Therefore, in absence of key/value pairs, no map is started – the value of myMap
will be the empty scalar. An empty scalar is loaded as empty string by Jackson, which leads to the error.
To mitigate this, you need to explicitly set the value to the empty map:
myMap: {}
{}
is a flow-style empty map.
Upvotes: 4