Символ вертикальной черты (|
) запускает скаляр блока YAML. Это означает, что все следующие строки являются буквальными строками и не подлежат дальнейшему синтаксическому анализу YAML.
В вашем коде происходит много странных вещей, давайте go поверх них:
public ArrayList<String> getProperties() {
ArrayList<String> finalString = new ArrayList<String>();
for(String entry : entries.keySet()) {
finalString.add(entry + ": " + entries.get(entry).toString());
}
return finalString;
}
Здесь вы вручную преобразуете отображение в список строк. Зачем ты это делаешь? Вы ожидаете, что окончательный файл YAML будет содержать пары ключ-значение в качестве сопоставления, поэтому вам не следует преобразовывать их в список строк.
Давайте обсудим, что здесь происходит, на небольшом примере: Предположим, у нас есть это java Карта:
Map<String, String> value = Map.of("foo", "bar");
Если мы напрямую сериализуем это в YAML, мы получим
foo: bar
, но если мы пропустим его через ваш метод, мы получим
- "foo: bar"
т.е. последовательность из одного скалярного значения - потому что мы вручную преобразовали запись отображения в строку! Это не то, что вам нужно.
propsProxyYaml.set("listeners", Arrays.asList(new ProxyYaml().getProperties()));
Вы вызываете Arrays.asList
для возвращаемого значения getProperties()
, которое имеет тип ArrayList<String>
, поэтому asList
вернет значение типа List<ArrayList<String>>
, которое имеет единственную запись, которая является списком, который вы построен. Непонятно, зачем вы звоните Arrays.asList
, если не хотите иметь список списков. Согласно желаемому результату YAML, это не то, что вам нужно.
Теперь давайте обсудим, что делает метод set
. Я действительно не знаю SimpleYAML, и, честно говоря, его документация ужасна, поскольку она в основном состоит только из автоматически сгенерированных документов API. Первый параметр метода называется path
, что означает, что это не простой ключ сопоставления.
Что очевидно происходит, так это то, что значение List<ArrayList<String>>
преобразуется в YAML последовательность с одним скалярным значением, и это скалярное значение содержит все созданные вами строковые значения, разделенные символами новой строки. Без надлежащей документации невозможно сказать, является ли это ожидаемым поведением или ошибкой. В любом случае смысла нет.
Теперь фактический YAML содержит отображение на своем root с одной записью, ключ которой является скаляром listeners
. Его значение - это список, содержащий другое отображение. Это означает, что тип, который вы действительно хотите сериализовать, - это
Map<String, List<Map<String, Object>>>
. Я предлагаю вам просто создать значение этого типа и использовать SnakeYAML API, у которого есть надлежащая документация о том, как его система сериализации работает. SimpleYAML в любом случае использует SnakeYAML под капотом, и, похоже, нет причин использовать плохо документированный API с удивительным поведением вместо хорошо документированного.
Вы также можете создать собственный класс Java вместо используя Map
с. Тогда ключи станут полями класса.