用于对象初始化的Java CLI参数语法

时间:2011-02-07 22:36:16

标签: java parsing properties posix command-line-arguments

我正在寻找一种工具,它允许我使用命令行样式(最好是POSIX)字符串来初始化对象的属性和属性。

例如,您将为其提供格式如下的String输入:

String input = "--firstName=John --MiddleName=\"Louis Victor\" --lastName=Smith";

...它会在给定对象上setFirstName("John")setMiddleName("Louis Victor")setLastName("Smith")。 (可能是一个JavaBean)

请注意,输入是单个String,而不是数组String[],就像许多流行的CLI参数“解析器”一样。

这与args4j类似,但我无法解决这个问题......我希望避免使用@annotations

有没有人可以使用代码/库/工具来完成此任务?

3 个答案:

答案 0 :(得分:4)

对于您的用例,忘记常规的CLI解析器,您需要一个定制的解决方案。如果你真的有这么简单的参数语法(参数总是以--开头,参数值中没有出现--),你可以使用一个简单的基于Guava的解决方案,比如这个类:

解析String Arguments

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才有意义)

定义Bean类

无论如何,我会使用这个值持有者类:

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

}

设置Bean属性

现在我们将使用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

这可能就是为什么你不能让它发挥作用的原因。

更新

在我看一下这个例子时,它看起来不像是原因。