优雅的方式来解析java中的控制台命令

时间:2016-06-15 14:56:10

标签: java command

所以我正在创建一个通过控制台命令工作的应用程序(想想"数据库new db_name")。什么是最优雅的方式来处理这类事情?

继承我的小型原型,基本上只有很多开关。我的意思是它有效,但是一旦我想要添加诸如输出所有参数之类的东西,如果你传递错误的一个或太少,它会变得有点混乱,所以我想知道是否有更好的选择:

public static void main(String[] args) {
    while (running) {
        Scanner in = new Scanner(System.in);
        String cmd = in.nextLine();

        parseCmd(cmd);
    }
}

private static void parseCmd(String s) {
    String[] cmd = s.split(" ");
    try {
        switch (cmd[0]) {
            case "exit":
                running = false;
                System.out.println("Shutting down...");
                break;

            case "database":
                switch (cmd[1]) {
                    case "new":
                        databases.add(new Database(cmd[2]));
                        break;

                    default:
                        System.out.println("Unknown parameter");
                        break;
                }
                break;

            default:
                System.out.println("Unknown command");
                break;
        }
    } catch (Exception ArrayIndexOutOfBoundsException) {
        System.out.println("Too few arguments passed");
    }
}

3 个答案:

答案 0 :(得分:2)

我不知道大多数优雅的方式,但我已经做了几次这样的事情并提出了这个解决方案。

为表示命令的“database”创建一个类,一旦找到字符串“database”,就会检索此类的实例并将其传递给剩余的参数,因此它可以执行其余的解析。

class DataBaseCommand implements Command {
    @Override
    public void eval(String[] args) {...}
}

然后,您可以将这些命令的静态映射映射到其名称:

private static final Map<String, Command> commands = new HashMap<>();

static {
    commands.put("database", new DataBaseCommand());
}
switch (cmd[0]) {
    case "exit":
        running = false;
        System.out.println("Shutting down...");
        break;
    default:
        if(commands.contains(cmd[0])) {
            commands.get(cmd[0]).eval(cmd);
        } else {
            System.out.println("Unknown command");
        }
        break;
}

答案 1 :(得分:0)

也许你可以使用一个为你做很多命令解析的库,比如joptsimple?

答案 2 :(得分:0)

我建议使用http://jcommander.org/。它简单而优雅。在其中,您可以使用内置注释  例如,使用jcommander annotaions

创建一个这样的类
@Parameters(commandNames = {"test", "Manages dates"})
public class CommandOption {

    @Parameter(names = {"-e", "--exit"}, description = "bla bla")
    public boolean exit = false;


}

then in main method 


      public static void main(String... args){

        CommandOption opt = new CommandOption();
            JCommander jc = new JCommander(opt);

            jc.parse(args);

    //and now use 
      System.out.println("value" +opt.exit)
    }

然后可以将parmae​​ters作为java class传递 - 如果您可以创建jar然后java -jar 'jar' -e true

,则为真或更好