I'm trying to load a YAML file into an instance of a Map
. Is there a way to load it without defining the custom deserializer (eg using annotations?)?
This is an example of my YAML file:
- site: First Site
url: some_url
username: some_name
password: some_password
- site: Second Site
url: its_url
username: its_name
password: its_password
This is the java bean class to deserialize one "site configuration" into (generated by http://www.jsonschema2pojo.org/ ):
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import org.apache.commons.lang3.builder.ToStringBuilder;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"site",
"url",
"username",
"password"
})
public class SiteConfiguration {
@JsonProperty("site")
private String site;
@JsonProperty("url")
private String url;
@JsonProperty("username")
private String username;
@JsonProperty("password")
private String password;
/**
* No args constructor for use in serialization
*
*/
public SiteConfiguration() {
}
/**
*
* @param site
* @param username
* @param password
* @param url
*/
public SiteConfiguration(String site, String url, String username, String password) {
super();
this.site = site;
this.url = url;
this.username = username;
this.password = password;
}
@JsonProperty("site")
public String getSite() {
return site;
}
@JsonProperty("site")
public void setSite(String site) {
this.site = site;
}
@JsonProperty("url")
public String getUrl() {
return url;
}
@JsonProperty("url")
public void setUrl(String url) {
this.url = url;
}
@JsonProperty("username")
public String getUsername() {
return username;
}
@JsonProperty("username")
public void setUsername(String username) {
this.username = username;
}
@JsonProperty("password")
public String getPassword() {
return password;
}
@JsonProperty("password")
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return new ToStringBuilder(this).append("site", site).append("url", url).append("username", username).append("password", password).toString();
}
}
And finally, this is the code that deserializes the YAML above into Map
.
private static Map<String,SiteConfiguration> sites;
public static SiteConfiguration getSiteConfiguration(String key) {
if (sites == null) {
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
try {
// todo this finishes on: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.LinkedHashMap` out of START_ARRAY token
// sites = mapper.readValue(YamlReader.class.getClass().getResource("/site-configuration.yaml"), new TypeReference<Map<String,SiteConfiguration>>() {});
SiteConfiguration[] sitesArray = mapper.readValue(YamlReader.class.getClass().getResource("/site-configuration.yaml"), SiteConfiguration[].class);
sites = new HashMap<>();
for (SiteConfiguration site : sitesArray) { //todo is there Jackson built-in deserialization?
sites.put(site.getSite(), site);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return sites.get(key);
}
As you can see, I'm doing it in two steps. First I deserialize the file into an array of SiteConfiguration
instances, then I put those into a Map
where site
field represents the map key.
Is there a way to do the same while omitting the array of SiteConfiguration
instances? Is the only way to do it using a custom deserializer?
Change the structure of your YAML. If you want to deserialize your data as a map, it needs to start as a map in the YAML file. You have a sequence of mappings in your example, but you want a mapping of mappings.
https://yaml.org/spec/1.2/spec.html#id2759963
Example 2.4. Sequence of Mappings (players' statistics)
- name: Mark McGwire hr: 65 avg: 0.278 - name: Sammy Sosa hr: 63 avg: 0.288
Example 10.1. !!map Examples
Block style: !!map Clark : Evans Ingy : döt Net Oren : Ben-Kiki
Try this instead:
First Site:
site: First Site
url: some_url
username: some_name
password: some_password
Second Site:
site: Second Site
url: its_url
username: its_name
password: its_password
This structure works with Jackson 2.9.9 with no custom deserializers.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.