简体   繁体   中英

How to parse snake_case properties in SnakeYAML

Jackson provides a dead simple way to parse camel_case properties. For example:

jackson.yaml with snake_case properties:

customers:
  - first_name: "John"
    last_name: "Doe"
    age: 52

Code for parse:

ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("jackson.yaml");
Orders orders = objectMapper.readValue(inputStream, Orders.class);

But is there something similar in SnakeYaml (such as PropertyNamingStrategies.SNAKE_CASE option)?

PS For now, the only way I've found is to use the @YamlProperty annotation on each property separately

As far as I know SnakeYAML uses reflection inside, so because of that you need to have property names in your classes equal to property name in your YAML file.

So in your case if you have yaml file with snake case you would have to use property name in your classes with snake case.

See example below:

Customer.java

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Customer {
    private String first_name;
    private String last_name;
    private Integer age;
}

Order.java

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order {
    private List<Customer> customers;
}

Main.java

public class Main {

    @SneakyThrows
    public static void main(String[] args) {
        InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("jackson.yaml");

        Yaml yaml = new Yaml();
        Order order = yaml.loadAs(inputStream, Order.class);
        System.out.println(order);
    }
}

jackson.yaml

customers:
  - first_name: "John"
    last_name: "Doe"
    age: 52

Output:

Order(customers=[Customer(first_name=John, last_name=Doe, age=52)])

EDIT:

There is also an option to define TypeDescriptors which tells SnakeYAML how to map fields. See example below:

public class Main {

    @SneakyThrows
    public static void main(String[] args) {
        InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("jackson.yaml");

        TypeDescription customerDescriptor = new TypeDescription(Customer.class);
        customerDescriptor.substituteProperty("first_name", String.class, "getFirstName", "setFirstName");
        customerDescriptor.substituteProperty("last_name", String.class, "getLastName", "setLastName");
        customerDescriptor.setExcludes("firstName", "lastName");

        Constructor constructor = new Constructor(Customer.class);
        Representer representer = new Representer(new DumperOptions());

        constructor.addTypeDescription(customerDescriptor);
        representer.addTypeDescription(customerDescriptor);

        Yaml yaml = new Yaml(constructor, representer);
        Order order = yaml.loadAs(inputStream, Order.class);
        System.out.println(order);
    }
}

jackson.yaml

customers:
  - first_name: "John"
    last_name: "Doe"
    age: 52

Customer.java

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Customer {
    private String firstName;
    private String lastName;
    private Integer age;
}

Output:

Order(customers=[Customer(firstName=John, lastName=Doe, age=52)])

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM