SnakeYaml“找不到属性错误”

Posted

技术标签:

【中文标题】SnakeYaml“找不到属性错误”【英文标题】:SnakeYaml "Unable to find property error" 【发布时间】:2019-03-08 05:40:13 【问题描述】:

这是我的 config.yml 的一部分:

#Authenctication
AuthenticationConfig:
  AuthencticationType: LDAP
  LDAPConfig:
     LDAPUrl: ldap://localhost:389
     ConnectionType: simple
     LDAPSecurityConfig:
        RootDN: cn=manager,dc=maxcrc,dc=com
        RootPassword: secret
        UserSearchDN: ou=People,dc=maxcrc,dc=com
        GroupdSearchDB: ou=Groups,dc=maxcrc,dc=com

我有一个用于解析的类:

public class YamlConfiguraiton 
    private AuthenticationConfiguration AuthenticationConfig;

    public void setAuthenticationConfig(AuthenticationConfiguration AuthenticationConfig) 
        this.AuthenticationConfig = AuthenticationConfig;
    

    public AuthenticationConfiguration getAuthenticationConfig() 
        return this.AuthenticationConfig;
    

但是,当我运行时

try(InputStream in = new FileInputStream(new File(ymalPath))) 
            yamlConfig = yaml.loadAs(in, YamlConfiguraiton.class);
         catch (IOException e) 
            e.printStackTrace();
        

出现以下错误:

Exception in thread "main" Cannot create property=AuthenticationConfig for JavaBean=com.ibm.entity.matching.common.bootstrap.YamlConfiguraiton@e7860081
 in 'reader', line 2, column 1:
    AuthenticationConfig:
    ^
Unable to find property 'AuthenticationConfig' on class: com.ibm.entity.matching.common.bootstrap.YamlConfiguraiton
 in 'reader', line 3, column 4:
       AuthencticationType: LDAP
       ^

    at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:270)
    at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.construct(Constructor.java:149)
    at org.yaml.snakeyaml.constructor.Constructor$ConstructYamlObject.construct(Constructor.java:309)
    at org.yaml.snakeyaml.constructor.BaseConstructor.constructObjectNoCheck(BaseConstructor.java:204)
    at org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:193)
    at org.yaml.snakeyaml.constructor.BaseConstructor.constructDocument(BaseConstructor.java:159)
    at org.yaml.snakeyaml.constructor.BaseConstructor.getSingleData(BaseConstructor.java:146)
    at org.yaml.snakeyaml.Yaml.loadFromReader(Yaml.java:524)
    at org.yaml.snakeyaml.Yaml.loadAs(Yaml.java:518)
    at com.ibm.entity.matching.bootstrap.EntityMatching.boot(EntityMatching.java:55)
    at com.ibm.entity.matching.bootstrap.EntityMatching.main(EntityMatching.java:35)
Caused by: org.yaml.snakeyaml.error.YAMLException: Unable to find property 'AuthenticationConfig' on class: com.ibm.entity.matching.common.bootstrap.YamlConfiguraiton
    at org.yaml.snakeyaml.introspector.PropertyUtils.getProperty(PropertyUtils.java:159)
    at org.yaml.snakeyaml.introspector.PropertyUtils.getProperty(PropertyUtils.java:148)
    at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.getProperty(Constructor.java:287)
    at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:208)
    ... 10 more

为什么它抱怨找不到属性 AuthenticationConfig 而 AuthenticationConfig 只是实例变量的名称?

更新 在我将实例变量从“private”更改为“public”后,它们被 SnakeYaml 识别,但这不是我们所期望的。这些类未被识别为 JavaBean。

更新 我找到了根本原因。这是命名约定。如果您希望 SnakeYaml 解析您的 yaml 文件,则必须遵守 camelCase。 setter 和 getter 方法的名称也很重要。假设有一个私有的实例变量叫 ldapConfig,那么它的 getter 和 setter 的名字必须是 getLdapConfig 和 setLdapConfig,即使 getLDAPConfig 和 setLDAPConfig 也不行。

【问题讨论】:

你确定键AuthenticationConfig 应该有null 作为值(省略一个值就好像你指定了: Null)? YAML 文件应具有 .yaml 扩展名,除非这是不可能的(例如,如果您使用过时的文件系统)。 @Anthon 对不起,我忘记了缩进... AuthenticationConfig 是父目录。 【参考方案1】:

错误的主要原因是您需要在 POJO 类中定义 Yaml 文件中存在的所有属性(即YamlConfiguraiton)。

您可以使用以下代码跳过未定义的属性。

Representer representer = new Representer();
            representer.getPropertyUtils().setSkipMissingProperties(true);
            Yaml yaml = new Yaml(new Constructor(YamlConfiguraiton.class), representer);

首先,将 Yaml 文件中的属性名称重命名为 camelCase。

参考以下代码:-

代码:-

public class YamlReadCustom 

    private static String yamlPath = "/authentication.yaml";

    public static void main(String[] args) 
        Representer representer = new Representer();
        representer.getPropertyUtils().setSkipMissingProperties(true);
        Yaml yaml = new Yaml(new Constructor(Authentication.class), representer);
        try(InputStream in = YamlReadCustom.class.getResourceAsStream (yamlPath)) 
            Authentication authentication = yaml.loadAs(in, Authentication.class);
            System.out.println(authentication.toString());
         catch (IOException e) 
            e.printStackTrace();
        
    

身份验证:-

public class Authentication 
    private String authenticationConfig;
    private String authencticationType;
    private LdapConfig ldapConfig;

    //getters and setters

LdapConfig:-

public class LdapConfig 
    private String ldapUrl;
    private String connectionType;
    private Map<String, Object> ldapSecurityConfig;
    //getters and setters

authentication.yaml

authenticationConfig:
authencticationType: LDAP
ldapConfig:
  ldapUrl: ldap://localhost:389
  connectionType: simple
  ldapSecurityConfig:
    rootDn: cn=manager,dc=maxcrc,dc=com
    rootPassword: secret
    userSearchDn: ou=People,dc=maxcrc,dc=com
    groupdSearchDb: ou=Groups,dc=maxcrc,dc=com

【讨论】:

伙计,我很抱歉忘记更正缩进...请查看我对 yaml 文件的更新。谢谢。

以上是关于SnakeYaml“找不到属性错误”的主要内容,如果未能解决你的问题,请参考以下文章

Snakeyaml - 如何对流样式进行自定义控制

无法解析类org.yaml.snakeyaml.Yaml @Grab('org.yaml:snakeyaml:1.17')Jenkins管道

使用 SnakeYAML 的嵌套构造

SnakeYAML:解析时如何禁用下划线剥离?

如何解决snakeyaml NoSuchMethodError:getStyle()

使用 SnakeYAML 保持标签顺序