我正在寻找一种工具,它允许我使用命令行样式(最好是POSIX)字符串来初始化对象的属性和属性。
例如,您将为其提供格式如下的String
输入:
String input = "--firstName=John --MiddleName=\"Louis Victor\" --lastName=Smith";
...它会在给定对象上setFirstName("John")
,setMiddleName("Louis Victor")
和setLastName("Smith")
。 (可能是一个JavaBean)
请注意,输入是单个String
,而不是数组String[]
,就像许多流行的CLI参数“解析器”一样。
这与args4j类似,但我无法解决这个问题......我希望避免使用@annotations
。
有没有人可以使用代码/库/工具来完成此任务?
答案 0 :(得分:4)
对于您的用例,忘记常规的CLI解析器,您需要一个定制的解决方案。如果你真的有这么简单的参数语法(参数总是以--
开头,参数值中没有出现--
),你可以使用一个简单的基于Guava的解决方案,比如这个类:
public class ArgParser{
// split on (optional whitespace) + "--"
private final Splitter paramSplitter = Splitter.on(
Pattern.compile("\\s*\\-{2}")).omitEmptyStrings();
// find key=value (with optional double quotes around value)
private final Pattern keyValuePattern = Pattern
.compile("(.+?)=\"?(.*?)\"?$");
public Map<String, String> getParamValues(final String posixString){
final Map<String, String> paramValues = Maps.newLinkedHashMap();
Matcher matcher;
for(final String param : paramSplitter.split(posixString)){
matcher = keyValuePattern.matcher(param);
if(!matcher.find()){
throw new IllegalArgumentException("Bad parameter: " + param);
}
paramValues.put(matcher.group(1), matcher.group(2));
}
return paramValues;
}
}
<强>用法强>
final String input =
"--firstName=John --middleName=\"Louis Victor\" --lastName=Smith";
System.out.println(new ArgParser().getParamValues(input));
<强>输出强>
{firstName = John,middleName = Louis Victor,lastName = Smith}
现在你可以使用地图并将其用于像commons-beanutils这样的Bean库(我个人更喜欢Spring BeanWrapper,但是只有你使用Spring才有意义)
无论如何,我会使用这个值持有者类:
public class Name{
private String firstName;
private String middleName;
private String lastName;
@Override
public String toString(){
return Objects
.toStringHelper(this)
.add("first name", firstName)
.add("middle name", middleName)
.add("last name", lastName)
.toString();
}
// + getters & setters
}
现在我们将使用BeanUtils.populate(Object, Map)
来应用参数值,如下所示:
final String input =
"--firstName=John --middleName=\"Louis Victor\" --lastName=Smith";
final Map<String, String> paramValues =
new ArgParser().getParamValues(input);
final Name name = new Name();
BeanUtils.populate(name, paramValues);
System.out.println(name);
<强>输出:强>
姓名{名字= John,中间名= Louis Victor,姓氏= Smith}
BeanUtils.populate()
支持设置以下属性类型:
... String,boolean,int,long,float和double。 另外,这些数组设置器 类型(或相应的原语 类型)也可以识别。
来源: BeanUtilsBean.populate(Object, Map)
如果您需要超出该参数转换,您应该考虑使用Spring BeanWrapper,它非常强大,有很多built-in property editors,您可以添加custom property editors。只需更改代码:
final Name name = new Name();
final BeanWrapper wrapper = new BeanWrapperImpl(name);
wrapper.setPropertyValues(paramValues);
<强>参考:强>
答案 1 :(得分:3)
如果我理解正确,您正在寻找一个Java库来解析POSIX样式的命令行参数。我前段时间使用过JSAP而且非常酷(当时正在使用XML配置)。
答案 2 :(得分:-1)
此
-firstName John -lastName Smith
不是POSIX,你的意思是
--firstName John --lastName Smith
这可能就是为什么你不能让它发挥作用的原因。
在我看一下这个例子时,它看起来不像是原因。