Spring boot - Rest Call client without embedded tomcat
Asked Answered
G

5

15

I have been trying to figure out an issue with spring boot and as i am new to spring I thought of getting some help here.

I have a spring boot based java application which runs as a daemon and makes some GET request to a remote server. (Acts only as a client).

But my spring boot application internally starts an embedded tomcat container. My understanding is that if the java app acts as a server, it would need tomcat. But my application being only a consumer of remote machine's GET APIs, why would it need an embedded tomcat ?

In my pom file I have specified spring-boot-starter-web, on assumption that it is needed for even making GET calls.

But after doing some research on disabling embedded tomcat, I found a solution.

To make following changes,

@SpringBootApplication(exclude = {EmbeddedServletContainerAutoConfiguration.class, 
WebMvcAutoConfiguration.class})

& in application.yml

spring:
   main:
      web-environment: false

With the application.yml changes, my jar is not even getting started, aborts directly, without even logging anything in logback logs.

Now, if i remove the application.yml change, my jar starts (only with first change in @SpringBootApplication anno.) but goes into some exception.

 [main] o.s.boot.SpringApplication               : Application startup failed

org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.

My Doubts here are,

1) Is tomcat, be it standalone or embedded, really needed for a application which just makes GET API calls to remote machine ?

2) How do i overcome this exception and safely remove the embedded tomcat and still perform the GET API calls ?

Getupandgo answered 24/7, 2018 at 9:11 Comment(1)
I don't think you need spring-boot-starter-web to make HTTP calls. Use basic spring-boot-starter and use the spring-web dependency.Perfectly
B
14

You seem to be on completely the wrong track here, starting from a web application template and then trying to turn off the web application aspect.

Far better to start from a regular commandline client template and go from there, as detailed in the relevant Spring Guide.

Basically the application reduces to

@SpringBootApplication
public class Application {

private static final Logger log = LoggerFactory.getLogger(Application.class);

public static void main(String args[]) {
    SpringApplication.run(Application.class);
}

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
    return builder.build();
}

@Bean
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
    return args -> {
        Quote quote = restTemplate.getForObject(
                "http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
        log.info(quote.toString());
    };
}
}

And the pom to

    <dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
</dependencies>
Bamby answered 24/7, 2018 at 9:25 Comment(4)
removing spring-boot-starter-web and adding spring-boot-starter and adding spring-web did the work. Thanks a lot.Getupandgo
It's not meant to be a web application template though, it's meant to be a high level generic web template. If you don't need the web server part, you can just disable it : docs.spring.io/spring-boot/docs/current/reference/html/…Planoconvex
FYI, the link to the relevant Spring Guide DOES have spring-boot-starter-web in the pom, and using it would produce the same problem the OP is having. You've got the correct pom here in the answer, though.Psycho
Need something similar handling http request without http server. Using the flag spring.main.web-application-type=none give the exception "No ServletContext set".Accusative
F
5

I had this problem. All I wanted was to have a Client making REST requests. Unfortunately I had a dependency which was embedding Jetty, and Jetty was always started.

In order to disable Jetty all I needed to do was to add in applications.properties the following entry:

spring.main.web-application-type=none

That fixed it.

Flowerpot answered 18/3, 2019 at 9:40 Comment(0)
S
3

Here is the most simple solution for me, make spring boot application just a restful api consumer.

Replace the dependence

implementation("org.springframework.boot:spring-boot-starter-web")

with

implementation("org.springframework.boot:spring-boot-starter-json")

RestTemplate and jackson are available in the project without embedded tomcat.

Scrubby answered 15/10, 2020 at 1:34 Comment(0)
R
0

Answering your questions:

1) embedded by defaut - not needed for clients HTTP requests;

2) You can use CommandLineRunner for spring boot applications without any web:

@SpringBootApplication
public class SpringBootConsoleApplication implements CommandLineRunner {

    public static void main(String[] args) {            
        SpringApplication.run(SpringBootConsoleApplication.class, args);
    }

    @Override
    public void run(String... args) {
        // TODO: start you thread here to execute client HTTP REST requests (or any other job you need)
    }
}

This will disable web completelly - no issues with manual miss-configuration.

Here is some docs: http://www.baeldung.com/spring-boot-console-app

You also need replase spring-boot-starter-web dependency with spring-boot-starter:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
Raffish answered 24/7, 2018 at 9:24 Comment(1)
Dependency spring-boot-starter does not come with REST client (i.e. RestTemplate), so to have it, one must specify spring-web + jackson dependency in pom.xml. Dependency spring-boot-starter-web also has it, but will make your application a web server too, starting by default on port 8080.Normalize
D
-1

From your question, i assume you want your application to keep running in background and it makes some get calls in it's life cycle. If that's the case, then

  1. answering your first question, yes, you need an embedded tomcat or jetty or need to deploy your application to an external application server.
  2. Second, to get rid of the exception your facing, don't exclude EmbeddedServletContainerAutoConfiguration and WebMvcAutoConfiguration class as it's needed for default embedded tomcat auto configuration.
Delenadeleon answered 24/7, 2018 at 9:22 Comment(1)
The question makes no reference to having to serve HTTP requests, so a web server is not required.Perfectly

© 2022 - 2024 — McMap. All rights reserved.