在配置文件中,我有多个数组值,例如电话簿的名称。
<configuration>
<phonebook>
<name>John</name>
<name>Mary</name>
</phonebook>
</configuration>
我想通过BeanHelper(或其他方式)将这些内容读入此bean:
public interface Phonebook {
public void setName(String[] names);
public String[] getName();
}
或理想情况下使用列表java.util.List<String>
而不是数组String[]
。
界面的实现很简单:
public class MyPhonebook implements Phonebook {
private String[] names;
@Override
public void setName(String[] names) {
this.names = names;
}
@Override
public String[] getName() {
return names;
}
@Override
public String toString() {
return String.join("; ", names);
}
}
主要看起来像这样:
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.ConfigurationRuntimeException;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.configuration.beanutils.BeanHelper;
import org.apache.commons.configuration.beanutils.XMLBeanDeclaration;
public class Main {
private static Phonebook myPhonebook;
private static XMLConfiguration config;
public static void main(String[] args) {
// read the configuration
String configFile = "config.xml";
try {
config = new XMLConfiguration();
// config.setAttributeSplittingDisabled(true);
config.setFileName(configFile);
config.load();
} catch (ConfigurationException e) {
e.printStackTrace();
}
// this is to see which keys and values are inside the configuration
config.getKeys().forEachRemaining(
s -> System.out.println(s + " : " + config.getProperty(s)));
// try to create the bean
try {
XMLBeanDeclaration declaration = new XMLBeanDeclaration(config,
"phonebook");
declaration.getBeanProperties().forEach(
(k, v) -> System.out.println(k + " : " + v));
myPhonebook = (Phonebook) BeanHelper.createBean(declaration,
MyPhonebook.class);
} catch (ConfigurationRuntimeException e) {
e.printStackTrace();
}
// print out the bean
System.out.println(myPhonebook);
}
}
尝试创建bean时这不起作用,我得到ConfigurationRuntimeException
引起的UnsupportedOperationException
:
java.lang.UnsupportedOperationException: Unable to handle collection of type : [Ljava.lang.String; for property name
at org.apache.commons.configuration.beanutils.BeanHelper.createPropertyCollection(BeanHelper.java:335)
at org.apache.commons.configuration.beanutils.BeanHelper.initBean(BeanHelper.java:213)
at org.apache.commons.configuration.beanutils.DefaultBeanFactory.initBeanInstance(DefaultBeanFactory.java:108)
at org.apache.commons.configuration.beanutils.DefaultBeanFactory.createBean(DefaultBeanFactory.java:64)
at org.apache.commons.configuration.beanutils.BeanHelper.createBean(BeanHelper.java:390)
... 2 more
我必须改变的第一件事是XML文件的布局,以匹配XMLBeanDeclaration和XMLConfiguration的文档:
<configuration>
<phonebook name="John,Mary" />
</configuration>
如果我运行该程序,它会正常终止,我的输出是:
phonebook[@name] : [John, Mary]
name : Mary
Mary
这意味着XMLConfiguration
正确地标识了属性名称中具有数组的配置文件,但不知何故XMLBeanDeclaration没有。它总是只取最后一个值。
我提出了一个解决方案,它或多或少地通过滥用可以在数组中读取单个String
的事实来工作。我添加了行config.setAttributeSplittingDisabled(true);
。结果如下:
phonebook[@name] : John,Mary
name : John,Mary
John; Mary
在这种情况下,似乎在创建bean时BeanHelper
实现了数组,并且能够选择正确的方法。
由于这会使我的配置稍微不灵活,我想知道是否有可能让XMLBeanDeclaration
在较早阶段处理数组以避免调用config.setAttributeSplittingDisabled(true);
?
我使用的是Java 8,Configuration 1.10和BeanUtils 1.9.2。