用Spring Boot创建CLI应用

因为我觉得我已经开始看到一种可以写得很整洁的方法,所以我打算总结一下。

环境

    • Java 1.8.0_91

 

    • Maven 3.3.9 (Maven wrapper)

 

    • Spring Boot 1.4.3.RELEASE

 

    Apache Commons CLI 1.3.1
$ ./mvnw -version
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T01:41:47+09:00)
Maven home: /Users/yo1000/.m2/wrapper/dists/apache-maven-3.3.9-bin/2609u9g41na2l7ogackmif6fj2/apache-maven-3.3.9
Java version: 1.8.0_91, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_91.jdk/Contents/Home/jre
Default locale: ja_JP, platform encoding: UTF-8
OS name: "mac os x", version: "10.11.5", arch: "x86_64", family: "mac"

使用的东西 de

    • Spring Boot

 

    Apache Commons CLI

摘录依存关系的部分。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <commons-cli.version>1.3.1</commons-cli.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    <dependency>
        <groupId>commons-cli</groupId>
        <artifactId>commons-cli</artifactId>
        <version>${commons-cli.version}</version>
    </dependency>
</dependencies>

要做的事

    • オプション付きパラメタの受け取り

 

    • オプション無しパラメタの受け取り

 

    • オプションに対するヘルプの表示

 

    • パイプされた標準入力の受け取り

 

    エラーハンドリング

配置成可作为CLI应用启动的形式。

在Spring Boot中,当创建CLI应用程序时的基础知识。创建一个实现org.springframework.boot.CommandLineRunner接口的组件。

如果创建这样一个类,当从终端启动应用程序时,将调用run方法。

@Component
public class DemoCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) {
        // 以下 ここに処理を実装していく
    }
}

处理参数

由于使用了Apache Commons CLI,处理命令行参数非常简单。可以执行以下操作。

Options options = new Options();
options.addOption("?", "help", false, "Print this message.");
options.addOption("o", "output", true, "Output directory.");
// void run(String... args) throws Exception {..}
CommandLine cl = new DefaultParser().parse(options, args);
if (cl.hasOption("o")) {..}
String output = cl.getOptionValue("o");
// どちらもパラメタの内容自体は同じ
String[] params = cl.getArgs();
List<String> paramList = cl.getArgList();
if (cl.hasOption("?")) {
    new HelpFormatter().printHelp("demo [-o <arg>]", options)
}

如上所述,参数可以非常简单地处理。

处理标准输入

如果是CLI应用程序,可以从标准输入接收值,并且可以通过管道连接进行处理,这样感觉很聪明,但是在这里不能使用Apache Commons CLI进行处理。使用System.in,可以处理标准输入,如下所示。

// パイプされた標準入力を受け取ると、対話式 CLI に使用する System.console() は null を返す
if (System.console() == null) {
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
        String stdin = reader.lines().collect(Collectors.joining());
    } catch (IOException e) {
        ..
    }
}

只要了解了处理已经传输的标准输入的方法,处理起来并不复杂。

错误处理

因为我使用了 Spring,所以通过 AOP 来集中处理异常并将其输出到标准错误流非常简单方便。

@Aspect
@Component
public class ExceptionHandlerAdvice {
    @Around("execution(* org.springframework.boot.CommandLineRunner+.run(..))")
    public void handleException(ProceedingJoinPoint joinPoint) {
        try {
            joinPoint.proceed()
        } catch (Exception e) {
            System.err.println(e.getMessage())
        }
    }
}

其他

由于使用Spring Boot,在作为CLI应用程序时,我们会抑制横幅显示和框架日志输出等内容。

通过将以下文件放置在src/resources/下,可以抑制CLI应用程序中不需要的日志输出。

spring:
  main:
    banner-mode: log
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
        </encoder>
    </appender>
    <root level="ERROR">
        <appender-ref ref="CONSOLE_APPENDER"/>
    </root>
</configuration>

如何启动

最后,让我们确认一下创建的 CLI 应用程序的启动方法。

如果尚未创建可执行的JAR文件,我们将直接从Maven启动。在这种情况下,参数传递的方式有一点不同。

$ java -jar cli.jar -o oParam nonOptionParam
$ ./mvnw spring-boot:run -Drun.arguments=-o,oParam,nonOptionParam

我认为通过以上的内容,我们已经基本了解了使用Spring Boot创建CLI应用程序时需要考虑的方面。

我已经创建了一个包含这些内容的 CLI 应用程序,你可以参考一下(虽然是 Kotlin 项目)。
链接:https://github.com/yo1000/pdf2img

广告
将在 10 秒后关闭
bannerAds