简体   繁体   中英

Receive input from command line with Spring Boot

So I have a really small Spring Boot command line application (There is no embedded tomcat server or anything that would make it a web application) with a single class where I try to use the Scanner class from java.util to read input from the user. This does not work at all. I thought it would be pretty basic stuff in Spring Boot, but all of my searches both on SO or tutorials have yielded no results. What's the best way to go about it? or is Spring Boot just not for what I want to do?

Here's my class:

package test;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.util.Scanner;

@SpringBootApplication
public class MyApplication implements CommandLineRunner {

    private static Logger LOG = LoggerFactory
        .getLogger(MyApplication.class);

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(MyApplication.class);
        app.run(args);
    }

    @Override
    public void run(String... args) throws Exception {
        LOG.info("EXECUTING : command line runner");

        Scanner in = new Scanner(System.in);

        System.out.println("What is your name?");
        String name = in.next();
        System.out.println("Hello " + name + " welcome to spring boot" );
    }
}

The exception being thrown is:

2019-05-29 11:31:29.116  INFO 4321 --- [           main] test.MyApplication  : EXECUTING : command line runner
2019-05-29 11:31:29.119  INFO 4321 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-05-29 11:31:29.124 ERROR 4321 --- [           main] o.s.boot.SpringApplication               : Application run failed

java.lang.IllegalStateException: Failed to execute CommandLineRunner
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:816) ~[spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
        at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:797) ~[spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:324) ~[spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
        at com.jaletechs.png.PrimeNumberGeneratorApplication.main(MyApplication.java:19) [main/:na]
Caused by: java.util.NoSuchElementException: null
        at java.util.Scanner.throwFor(Scanner.java:862) ~[na:1.8.0_201]
        at java.util.Scanner.next(Scanner.java:1371) ~[na:1.8.0_201]
        at test.MyApplication.run(MyApplication.java:27) [main/:na]
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:813) ~[spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
        ... 3 common frames omitted

or is Spring Boot just not for what I want to do?

You are right.

Spring Boot application is a server one (like any other .war) and runs in an embedded Tomcat. What kind of Scanner here can be?

If you want to interact with it - you should create REST controller and send/receive data through endpoints.

Spring boot is not designed for any kind of general purpose usages. It has specific purposes. We should not always think about how to use Spring Boot for any kind of requirements. I know Spring Boot has become very popular. To your question, if you want to create an interactive application/program, you have to do in a simple manner. I just provide below the code snippet.

public class Interactive
{

  public static void main (String[] args)
  {
    // create a scanner so we can read the command-line input
    Scanner scanner = new Scanner(System.in);
    System.out.print("Enter your name ? ");
    String username = scanner.next();
    System.out.print("Enter your age ? ");
    int age = scanner.nextInt();

    //Print all name, age etc
  }

}

Hope this may be your requirement. Again Spring Boot application can not be stated as interactive in true sense. Many interpretations are there. Spring Boot is suitable for client server architecture.

So I discovered a way to make it work by trying out a normal gradle application (not spring boot). I ran into the same problem, and the solution was to add a line in my build.gradle file to wire up the default stdin

In a normal java gradle application:

run {
    standardInput = System.in
}

but in the Spring Boot application, I added the following line:

bootRun {
    standardInput = System.in
}

Turns out Spring Boot could handle a Command Line Application after all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM