Spring boot - 没有嵌入式 tomcat 的 Rest Call 客户端
Posted
技术标签:
【中文标题】Spring boot - 没有嵌入式 tomcat 的 Rest Call 客户端【英文标题】:Spring boot - Rest Call client without embedded tomcat 【发布时间】:2018-12-31 20:27:16 【问题描述】:我一直在尝试解决 spring boot 的问题,由于我是 spring 新手,所以我想在这里获得一些帮助。
我有一个基于 Spring Boot 的 Java 应用程序,它作为守护进程运行并向远程服务器发出一些 GET 请求。 (仅作为客户端)。
但我的 Spring Boot 应用程序在内部启动了一个嵌入式 tomcat 容器。 我的理解是,如果 java 应用程序充当服务器,它将需要 tomcat。但是我的应用程序只是远程机器的 GET API 的消费者,为什么它需要一个嵌入式 tomcat?
在我的 pom 文件中,我指定了 spring-boot-starter-web, 假设即使进行 GET 调用也需要它。
但是在对禁用嵌入式tomcat进行了一些研究之后,我找到了解决方案。
要进行以下更改,
@SpringBootApplication(exclude = EmbeddedServletContainerAutoConfiguration.class,
WebMvcAutoConfiguration.class)
& 在application.yml中
spring:
main:
web-environment: false
随着 application.yml 的变化,我的 jar 甚至没有启动,直接中止,甚至没有在 logback 日志中记录任何内容。
现在,如果我删除 application.yml 更改,我的 jar 将启动(仅在 @SpringBootApplication anno 中进行第一次更改。)但会出现一些异常。
[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.
我的疑惑是,
1) 仅对远程机器进行 GET API 调用的应用程序是否真的需要 tomcat,无论是独立的还是嵌入式的?
2) 我如何克服这个异常并安全地移除嵌入式 tomcat 并仍然执行 GET API 调用?
【问题讨论】:
我认为您不需要spring-boot-starter-web
来进行 HTTP 调用。使用基本的spring-boot-starter
并使用spring-web
依赖项。
【参考方案1】:
对我来说这是最简单的解决方案,让 spring boot 应用程序只是一个安静的 api 使用者。
替换依赖
implementation("org.springframework.boot:spring-boot-starter-web")
与
implementation("org.springframework.boot:spring-boot-starter-json")
RestTemplate
和jackson
在没有嵌入tomcat 的项目中可用。
【讨论】:
【参考方案2】:我遇到了这个问题。我想要的只是让客户端发出 REST 请求。不幸的是,我有一个嵌入 Jetty 的依赖项,并且 Jetty 总是启动。
为了禁用 Jetty,我需要做的就是在 applications.properties 中添加以下条目:
spring.main.web-application-type=none
这样就解决了。
【讨论】:
【参考方案3】:回答你的问题:
1) 默认嵌入 - 客户端 HTTP 请求不需要;
2) 您可以在没有任何 web 的情况下将 CommandLineRunner 用于 Spring Boot 应用程序:
@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)
这将完全禁用网络 - 手动错误配置没有问题。
这里有一些文档: http://www.baeldung.com/spring-boot-console-app
你还需要用 spring-boot-starter 替换 spring-boot-starter-web 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
【讨论】:
依赖 spring-boot-starter 不附带 REST 客户端(即 RestTemplate),因此必须在 pom.xml 中指定 spring-web + jackson 依赖。依赖 spring-boot-starter-web 也有它,但是会让你的应用程序也成为一个 web 服务器,默认从端口 8080 开始。【参考方案4】:您似乎完全走错了路,从 Web 应用程序模板开始,然后尝试关闭 Web 应用程序方面。
最好从常规命令行客户端模板开始并从那里开始,如relevant Spring Guide 中所述。
基本上应用程序简化为
@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());
;
和 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>
【讨论】:
删除 spring-boot-starter-web 并添加 spring-boot-starter 并添加 spring-web 完成了工作。非常感谢。 它并不是一个 Web 应用程序模板,而是一个高级通用 Web 模板。如果您不需要 Web 服务器部分,您可以禁用它:docs.spring.io/spring-boot/docs/current/reference/html/… 仅供参考,相关 Spring Guide 的链接在 pom 中有 spring-boot-starter-web ,使用它会产生与 OP 相同的问题。不过,您在答案中找到了正确的 pom。【参考方案5】:根据您的问题,我假设您希望您的应用程序继续在后台运行,并在其生命周期中进行一些 get 调用。如果是这样的话,那么
-
回答您的第一个问题,是的,您需要嵌入式 tomcat 或
码头或需要将您的应用程序部署到外部应用程序
服务器。
第二,摆脱你面临的异常,不要排除
EmbeddedServletContainerAutoConfiguration 和
WebMvcAutoConfiguration 类,因为它是默认嵌入所需的
tomcat 自动配置。
【讨论】:
该问题没有提及必须服务 HTTP 请求,因此不需要 Web 服务器。以上是关于Spring boot - 没有嵌入式 tomcat 的 Rest Call 客户端的主要内容,如果未能解决你的问题,请参考以下文章
Spring boot - 没有嵌入式 tomcat 的 Rest Call 客户端
Elastic Beanstalk 工作层上的 Spring Boot
如何在嵌入式 tomcat 服务器上部署 Spring Boot Web 应用程序,来自 Spring Boot 本身
使用 IntelliJ 部署启用嵌入式 tomcat 的 spring-boot 应用程序