SpringBoot 无法识别来自多模块 Java 应用程序中另一个模块的 RestController
SpringBoot doesn't recognize RestController from another module in multi module Java application
我已经花了很多时间,但还是无法解决这个(配置)问题。
技术栈:Java(1.8)、Springboot(starter-parent、starter-web)、Maven、IntelliJ IDEA
描述: 尝试创建一个多模块 Java 应用程序(最初)由 2 个模块组成:
- core module : 主模块(主要业务逻辑,其他模块应该通过这个模块看到和交互)。此模块包含主要应用程序 class.
- webgateway 模块:简单的 Rest 控制器,它将映射请求并调用 core 模块
问题: Springboot 没有 load/scan webgateway 模块中的 RestController => 发送 http 请求时出现 404 错误
Github 回购 : https://github.com/Sorin-J/Greeter
项目配置:
Greeter
|
+ pom.xml (parent pom)
|
+ -- core
| |
| + ...
| |
| + pom.xml
|
+ -- webgateway
|
+ ...
|
+ pom.xml (depends on core pom.xml)
父级 pom.xml :
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bet.jbs</groupId>
<artifactId>Greeter</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>core</module>
<module>webgateway</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
核心模块pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Greeter</artifactId>
<groupId>com.bet.jbs</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>core</artifactId>
</project>
webgateway 模块 pom.xml :
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Greeter</artifactId>
<groupId>com.bet.jbs</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>webgateway</artifactId>
<dependencies>
<dependency>
<groupId>com.bet.jbs</groupId>
<artifactId>core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
MainApplication class 来自 core 模块:
package com.bet.jbs.core;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = {"com.bet.jbs.core", "com.bet.jbs.webgateway"})
@EnableAutoConfiguration
public class MainApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(MainApplication.class, args);
}
}
GreetingController class 来自 webgateway 模块:
package com.bet.jbs.webgateway.controller;
import com.bet.jbs.core.util.GreetingGenerator;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
@RequestMapping(value = "/webgreeting", method = RequestMethod.GET)
public String getGreeting() {
return "WEBGATEWAY module says " + GreetingGenerator.getRandomGreeting();
}
}
只是为了测试如果相同的 REST 控制器位于 core 模块中是否可以正常工作,我创建了一个类似的 GreetingController class 也在 core 模块中(这个工作正常):
package com.bet.jbs.core.controller;
import com.bet.jbs.core.util.GreetingGenerator;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/*
* This REST controller should not be in the CORE component.
* It is just for proving that this controller is recognized and the other one from WEBGATEWAY component is not.
*
*/
@RestController
public class GreetingController {
@RequestMapping(value = "/coregreeting", method = RequestMethod.GET)
public String getGreeting() {
return "CORE module says " + GreetingGenerator.getRandomGreeting();
}
}
Spring Boot 主应用程序在 core
模块中,它不依赖于 webgateway
模块。因此,带有控制器的 class 将不会在运行时出现,并且无法被 spring 发现。
Fix: 添加对webgateway
的依赖到核心或者将launcher/mainclass移动到webgateway
模块.
您还可以使用第三个模块来启动并依赖于 core
和 webgateway
。
自从前一天以来,我一直被这个问题困扰...下面的解决方案肯定会为您节省很多时间!
我是这样解决的:
为 main 创建一个单独的模块 Application
class.
x-service
- pom.xml (parent)
- child1-模块
- pom.xml
- child2-模块
- pom.xml
- app-module
- pom.xml(包含 child1 和 child2 的依赖项)
- src/main/java/Application.java
在具有应用程序 class.
的模块的 pom 中添加所有模块作为依赖项
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>x-service</artifactId>
<groupId>com.a.b.c</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>app-module</artifactId>
<dependencies>
<dependency>
<groupId>com.a.b.cs</groupId>
<artifactId>child1-module</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.a.b.cs</groupId>
<artifactId>child1-module</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
将主 pom 保持为 parent pom.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>child1-module</module>
<module>child2-module</module>
<module>app-module</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.a.b.c</groupId>
<artifactId>x-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.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-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</build>
在所有 child 个 pom 中将 parent pom 工件添加为 parent。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dxg-service</artifactId>
<groupId>com.a.b.c</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.a.b.c</groupId>
<artifactId>child1-module</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.a.b.c</groupId>
<artifactId>child2-modulde</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
这里有更多详细信息:
https://medium.com/macoclock/how-create-multi-module-project-in-intellij-on-macos-50f07e52b7f9
我已经添加了正确的依赖项,但 Spring 启动仍然没有找到我的新控制器。似乎 IntelliJ IDEA (2020.3.2) 或 Maven (3.3.6) 在添加模块时未正确更新。这为我解决了:
专家:
清理 + 在父项目上安装
在文件菜单中的 IntelliJ 中Invalidate Caches / Restart..
如前所述,您应该在其中设置 spring web starter 的父 pom,并且其他模块必须将该父 pom 作为其父 pom。小心将您的根 pom 项目添加到 Maven。在 IDE 中打开 Maven 并添加 pom.
我已经花了很多时间,但还是无法解决这个(配置)问题。
技术栈:Java(1.8)、Springboot(starter-parent、starter-web)、Maven、IntelliJ IDEA
描述: 尝试创建一个多模块 Java 应用程序(最初)由 2 个模块组成:
- core module : 主模块(主要业务逻辑,其他模块应该通过这个模块看到和交互)。此模块包含主要应用程序 class.
- webgateway 模块:简单的 Rest 控制器,它将映射请求并调用 core 模块
问题: Springboot 没有 load/scan webgateway 模块中的 RestController => 发送 http 请求时出现 404 错误
Github 回购 : https://github.com/Sorin-J/Greeter
项目配置:
Greeter
|
+ pom.xml (parent pom)
|
+ -- core
| |
| + ...
| |
| + pom.xml
|
+ -- webgateway
|
+ ...
|
+ pom.xml (depends on core pom.xml)
父级 pom.xml :
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bet.jbs</groupId>
<artifactId>Greeter</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>core</module>
<module>webgateway</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
核心模块pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Greeter</artifactId>
<groupId>com.bet.jbs</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>core</artifactId>
</project>
webgateway 模块 pom.xml :
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Greeter</artifactId>
<groupId>com.bet.jbs</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>webgateway</artifactId>
<dependencies>
<dependency>
<groupId>com.bet.jbs</groupId>
<artifactId>core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
MainApplication class 来自 core 模块:
package com.bet.jbs.core;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = {"com.bet.jbs.core", "com.bet.jbs.webgateway"})
@EnableAutoConfiguration
public class MainApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(MainApplication.class, args);
}
}
GreetingController class 来自 webgateway 模块:
package com.bet.jbs.webgateway.controller;
import com.bet.jbs.core.util.GreetingGenerator;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
@RequestMapping(value = "/webgreeting", method = RequestMethod.GET)
public String getGreeting() {
return "WEBGATEWAY module says " + GreetingGenerator.getRandomGreeting();
}
}
只是为了测试如果相同的 REST 控制器位于 core 模块中是否可以正常工作,我创建了一个类似的 GreetingController class 也在 core 模块中(这个工作正常):
package com.bet.jbs.core.controller;
import com.bet.jbs.core.util.GreetingGenerator;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/*
* This REST controller should not be in the CORE component.
* It is just for proving that this controller is recognized and the other one from WEBGATEWAY component is not.
*
*/
@RestController
public class GreetingController {
@RequestMapping(value = "/coregreeting", method = RequestMethod.GET)
public String getGreeting() {
return "CORE module says " + GreetingGenerator.getRandomGreeting();
}
}
Spring Boot 主应用程序在 core
模块中,它不依赖于 webgateway
模块。因此,带有控制器的 class 将不会在运行时出现,并且无法被 spring 发现。
Fix: 添加对webgateway
的依赖到核心或者将launcher/mainclass移动到webgateway
模块.
您还可以使用第三个模块来启动并依赖于 core
和 webgateway
。
自从前一天以来,我一直被这个问题困扰...下面的解决方案肯定会为您节省很多时间!
我是这样解决的:
为 main 创建一个单独的模块
Application
class.x-service
- pom.xml (parent)
- child1-模块
- pom.xml
- child2-模块
- pom.xml
- app-module
- pom.xml(包含 child1 和 child2 的依赖项)
- src/main/java/Application.java
在具有应用程序 class.
的模块的 pom 中添加所有模块作为依赖项<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>x-service</artifactId> <groupId>com.a.b.c</groupId> <version>0.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>app-module</artifactId> <dependencies> <dependency> <groupId>com.a.b.cs</groupId> <artifactId>child1-module</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>com.a.b.cs</groupId> <artifactId>child1-module</artifactId> <version>0.0.1-SNAPSHOT</version> <scope>compile</scope> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <executable>true</executable> </configuration> </plugin> </plugins> </build>
将主 pom 保持为 parent pom.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <packaging>pom</packaging> <modules> <module>child1-module</module> <module>child2-module</module> <module>app-module</module> </modules> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.2.RELEASE</version> <relativePath/> </parent> <groupId>com.a.b.c</groupId> <artifactId>x-service</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <java.version>1.8</java.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-web</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-checkstyle-plugin</artifactId> <version>3.0.0</version> </plugin> </plugins> </build>
在所有 child 个 pom 中将 parent pom 工件添加为 parent。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>dxg-service</artifactId> <groupId>com.a.b.c</groupId> <version>0.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.a.b.c</groupId> <artifactId>child1-module</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>com.a.b.c</groupId> <artifactId>child2-modulde</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies>
这里有更多详细信息: https://medium.com/macoclock/how-create-multi-module-project-in-intellij-on-macos-50f07e52b7f9
我已经添加了正确的依赖项,但 Spring 启动仍然没有找到我的新控制器。似乎 IntelliJ IDEA (2020.3.2) 或 Maven (3.3.6) 在添加模块时未正确更新。这为我解决了:
专家: 清理 + 在父项目上安装
在文件菜单中的 IntelliJ 中
Invalidate Caches / Restart..
如前所述,您应该在其中设置 spring web starter 的父 pom,并且其他模块必须将该父 pom 作为其父 pom。小心将您的根 pom 项目添加到 Maven。在 IDE 中打开 Maven 并添加 pom.