【问题标题】:Spring Boot: Cannot access REST Controller on localhost (404)Spring Boot:无法访问本地主机上的 REST 控制器(404)
【发布时间】:2015-09-27 20:45:54
【问题描述】:

我正在尝试调整 Spring Boot 网站上的 REST 控制器示例。 不幸的是,当我尝试访问 localhost:8080/item URL 时出现以下错误。

{
  "timestamp": 1436442596410,
  "status": 404,
  "error": "Not Found",
  "message": "No message available",
  "path": "/item"
}

POM:

<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>SpringBootTest</groupId>
   <artifactId>SpringBootTest</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <properties>
      <javaVersion>1.8</javaVersion>
      <mainClassPackage>com.nice.application</mainClassPackage>
      <mainClass>${mainClassPackage}.InventoryApp</mainClass>
   </properties>

   <build>
      <plugins>
         <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.3</version>
            <configuration>
               <source>${javaVersion}</source>
               <target>${javaVersion}</target>
            </configuration>
         </plugin>

         <!-- Makes the Spring Boot app executable for a jar file. The additional configuration is needed for the cmd: mvn spring-boot:repackage 
            OR mvn spring-boot:run -->
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>

            <configuration>
               <mainClass>${mainClass}</mainClass>
               <layout>ZIP</layout>
            </configuration>
            <executions>
               <execution>
                  <goals>
                     <goal>repackage</goal>
                  </goals>
               </execution>
            </executions>
         </plugin>

         <!-- Create a jar with a manifest -->
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
               <archive>
                  <manifest>
                     <mainClass>${mainClass}</mainClass>
                  </manifest>
               </archive>
            </configuration>
         </plugin>
      </plugins>
   </build>

   <dependencyManagement>
      <dependencies>
         <dependency>
            <!-- Import dependency management from Spring Boot. This replaces the usage of the Spring Boot parent POM file. -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>1.2.5.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
         </dependency>

         <!-- more comfortable usage of several features when developing in an IDE. Developer tools are automatically disabled when 
            running a fully packaged application. If your application is launched using java -jar or if it’s started using a special classloader, 
            then it is considered a 'production application'. Applications that use spring-boot-devtools will automatically restart whenever files 
            on the classpath change. -->
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
         </dependency>
      </dependencies>
   </dependencyManagement>

   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>

      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>

      <dependency>
         <groupId>com.google.guava</groupId>
         <artifactId>guava</artifactId>
         <version>15.0</version>
      </dependency>
   </dependencies>
</project>

入门应用:

package com.nice.application;
@SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan
public class InventoryApp {
   public static void main( String[] args ) {
      SpringApplication.run( InventoryApp.class, args );
   }
}

REST 控制器:

package com.nice.controller; 
@RestController // shorthand for @Controller and @ResponseBody rolled together
public class ItemInventoryController {
   public ItemInventoryController() {
   }

   @RequestMapping( "/item" )
   public String getStockItem() {
      return "It's working...!";
   }

}

我正在使用 Maven 构建这个项目。 以 jar (spring-boot:run) 和 IDE (Eclipse) 的形式启动它。

控制台日志:

2015-07-09 14:21:52.132  INFO 1204 --- [           main] c.b.i.p.s.e.i.a.InventoryApp          : Starting InventoryApp on 101010002016M with PID 1204 (C:\eclipse_workspace\SpringBootTest\target\classes started by MFE in C:\eclipse_workspace\SpringBootTest)
2015-07-09 14:21:52.165  INFO 1204 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@7a3d45bd: startup date [Thu Jul 09 14:21:52 CEST 2015]; root of context hierarchy
2015-07-09 14:21:52.661  INFO 1204 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'beanNameViewResolver': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
2015-07-09 14:21:53.430  INFO 1204 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2015-07-09 14:21:53.624  INFO 1204 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2015-07-09 14:21:53.625  INFO 1204 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.0.23
2015-07-09 14:21:53.731  INFO 1204 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2015-07-09 14:21:53.731  INFO 1204 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1569 ms
2015-07-09 14:21:54.281  INFO 1204 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2015-07-09 14:21:54.285  INFO 1204 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'characterEncodingFilter' to: [/*]
2015-07-09 14:21:54.285  INFO 1204 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2015-07-09 14:21:54.508  INFO 1204 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@7a3d45bd: startup date [Thu Jul 09 14:21:52 CEST 2015]; root of context hierarchy
2015-07-09 14:21:54.573  INFO 1204 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2015-07-09 14:21:54.573  INFO 1204 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)
2015-07-09 14:21:54.594  INFO 1204 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2015-07-09 14:21:54.594  INFO 1204 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2015-07-09 14:21:54.633  INFO 1204 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2015-07-09 14:21:54.710  INFO 1204 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2015-07-09 14:21:54.793  INFO 1204 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2015-07-09 14:21:54.795  INFO 1204 --- [           main] c.b.i.p.s.e.i.a.InventoryApp          : Started InventoryApp in 2.885 seconds (JVM running for 3.227)
2015-07-09 14:22:10.911  INFO 1204 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2015-07-09 14:22:10.911  INFO 1204 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2015-07-09 14:22:10.926  INFO 1204 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 15 ms

到目前为止我已经尝试过:

  • 使用应用程序名称 (InventoryApp) 访问 URL
  • 将另一个@RequestMapping("/") 放在ItemInventoryController 的班级级别

据我了解,使用 Spring Boot 时我不需要应用程序上下文。我说的对吗?

我还能做些什么来通过 URL 访问该方法?

【问题讨论】:

  • 你是如何运行应用程序的?你能包括一些日志吗?
  • 通过 Eclipse 和 mvn spring-boot:run (作为 jar)单独尝试。日志见上文(已编辑)
  • 从启动日志看,它似乎没有找到您的控制器,您的控制器类在哪个包中?
  • 它在一个单独的包中。具有 main 方法的起始类位于“应用程序”中,而控制器位于“控制器”包中。我看过一些例子(不是 spring.io 上的例子),它们也是以这种方式构建的。
  • 默认情况下,spring-boot 将扫描与您的应用程序类相同的包中的组件,或“低于”(相同前缀)的包。否则,您需要显式扫描它们,例如使用 @ComponentScan

标签: java rest spring-boot


【解决方案1】:

尝试将以下内容添加到您的 InventoryApp 类中

@SpringBootApplication
@ComponentScan(basePackageClasses = ItemInventoryController.class)
public class InventoryApp {
...

spring-boot 会扫描com.nice.application 下的包中的组件,所以如果你的控制器在com.nice.controller 中,你需要明确地扫描它。

【讨论】:

  • 我也有同样的问题。我尝试使用组件扫描,但没有:-(我的问题是:stackoverflow.com/questions/33000931/…
  • 请注意@SpringBootApplication 包括@Configuration
  • 将应用程序放在“根”包中似乎最简单,例如“org.whatever”和子包中的控制器、服务。
  • 我有同样的问题,但在找到这个解决方案之前,我发现它......更多。将您的 Spring Boot 应用程序类(其中定义了 main 方法)提升到控制器包的一级。然后控制器将对此可见并可以工作
  • 你也可以使用'@ComponentScan(basePackages = "com.nice.controller")'。组件默认扫描从路径开始,App 类在哪里,并且还扫描附属包。在这种情况下,您不需要使用 @ComponentScan 注释。它会自动执行。如果您有超过 1 个控制器,也可以将它们放在不同的包中,您可以将它们链接起来。在这种情况下,避免冲突很重要。
【解决方案2】:

添加到 MattR 的答案:

here 中所述,@SpringBootApplication 会自动插入所需的注解:@Configuration@EnableAutoConfiguration,还有@ComponentScan;但是,@ComponentScan 只会在与应用程序相同的包中查找组件,在本例中是您的com.nice.application,而您的控制器位于com.nice.controller。这就是你得到 404 的原因,因为应用程序在 application 包中找不到控制器。

【讨论】:

  • 如果从上面的解释中还不能完全清楚,带有@SpringBootApplication注解的类必须在你的目录结构中的ABOVE或与你想要的东西相同的级别找。例如,我有 com.app.configuration 和 com.app.controllers。我错误地将我的应用程序类放入 com.app.configuration,而 com.app.configuration 中的其他所有内容都运行良好,但 com.app.controllers 中没有任何内容被加载。我将我的 Application 类移动到 com.app 中,并且找到了其他地方的 bean,并且开始工作。对我来说是新手错误。
  • 添加 @ComponentScan(basePackages="com.base.package") 在我的情况下解决了它
  • 这真的很有帮助。
【解决方案3】:

使用以下代码执行服务后,我得到了相同的 404 响应

@Controller
@RequestMapping("/duecreate/v1.0")
public class DueCreateController {

}

回复:

{
"timestamp": 1529692263422,
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/duecreate/v1.0/status"
}

将其更改为以下代码后,我收到了正确的响应

@RestController
@RequestMapping("/duecreate/v1.0")
public class DueCreateController {

}

回复:

{
"batchId": "DUE1529673844630",
"batchType": null,
"executionDate": null,
"status": "OPEN"
}

【讨论】:

  • 以防其他读者看不到,@Controller -> @RestController
【解决方案4】:

SpringBoot 开发人员建议将您的主应用程序类定位在其他类之上的根包中。使用根包还允许使用 @ComponentScan 注释,而无需指定 basePackage 属性。 Detailed info 但请确保自定义根包存在。

【讨论】:

    【解决方案5】:

    有两种方法可以解决这个问题

    1. 将启动应用程序放在包结构的开头,然后将所有控制器放在其中。

      例子:

      包 com.spring.boot.app; - 你启动应用程序(即 Main Method -SpringApplication.run(App.class, args);)

      你在相同的包结构中休息控制器 例子 : 包 com.spring.boot.app.rest;

    2. 在 Bootup 包中显式定义 Controller。

    方法1更干净。

    【讨论】:

    • spring boot 讨厌应用程序类位于基础包以外的某个包下。如果基础包是 org.someapp 并且如果我们将它放在 org.someapp.app 下它会爆炸.. :-/跨度>
    • @PriyankThakkar 谢谢。这是我的问题
    【解决方案6】:

    我遇到了这个问题,您需要做的是修复您的软件包。如果你从http://start.spring.io/ 下载了这个项目,那么你的主类就在某个包中。例如,如果主类的包是:“com.example”,那么您的控制器必须在包中:“com.example.controller”。希望这会有所帮助。

    【讨论】:

    • 表示服务器已经启动,但是没有收到请求。
    • @AjayTakur 服务器已启动并运行,请求已发送但没有端点来处理它们。为了使 Controller 正常工作,它需要在正确的包中或添加额外的注解,以便 Spring Boot 扫描并启用它。
    【解决方案7】:

    您需要修改 Starter-Application 类,如下所示。

    @SpringBootApplication
    
    @EnableAutoConfiguration
    
    @ComponentScan(basePackages="com.nice.application")
    
    @EnableJpaRepositories("com.spring.app.repository")
    
    public class InventoryApp extends SpringBootServletInitializer {..........
    

    并更新 Controller、Service 和 Repository 包结构,如下所述。

    示例: REST-控制器

    package com.nice.controller; --> 必须修改为
    package com.nice.application.controller;

    您需要为 Spring Boot MVC 流程中的所有包遵循正确的包结构。

    因此,如果您正确修改项目捆绑包结构,那么您的 Spring Boot 应用程序将正常工作。

    【讨论】:

    • EnableAutoConfiguration 包含在@SpringBootApplication 中,所以添加它是没有用的。
    【解决方案8】:

    对我来说,我将 spring-web 而不是 spring-boot-starter-web 添加到我的 pom.xml 中

    当我将它从 spring-web 替换为 spring-boot-starter-web 时,所有映射都显示在控制台日志中。

    【讨论】:

      【解决方案9】:

      @RequestMapping( "/item" ) 替换为@GetMapping(value="/item", produces=MediaType.APPLICATION_JSON_VALUE)

      也许它会对某人有所帮助。

      【讨论】:

      • 它帮助我认识到我在@GetMapping 中写的是name 而不是value
      【解决方案10】:

      我有完全相同的错误,我没有提供基础包。给出正确的基础包,解决它。

      package com.ymc.backend.ymcbe;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.context.annotation.ComponentScan;
      
      @SpringBootApplication
      @ComponentScan(basePackages="com.ymc.backend")
      public class YmcbeApplication {
      
          public static void main(String[] args) {
              SpringApplication.run(YmcbeApplication.class, args);
          }
      
      }
      

      注意:不包括 .controller @ComponentScan(basePackages="com.ymc.backend.controller") 因为我 如果我有许多其他组件类,我的项目不会扫描 只需给.controller

      这是我的控制器示例:

      package com.ymc.backend.controller;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.CrossOrigin;
      import org.springframework.web.bind.annotation.PostMapping;
      import org.springframework.web.bind.annotation.RequestBody;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      
      @RestController
      @CrossOrigin
      @RequestMapping(value = "/user")
      public class UserController {
      
          @PostMapping("/sendOTP")
          public String sendOTP() {
              return "OTP sent";
          };
      
      
      }
      

      【讨论】:

        【解决方案11】:

        有时弹簧靴的行为很奇怪。我在应用程序类中指定了以下内容,它可以工作:

        @ComponentScan("com.seic.deliveryautomation.controller")
        

        【讨论】:

          【解决方案12】:

          我遇到了 404 问题,因为 Url Case Sensitivity

          例如 @RequestMapping(value = "/api/getEmployeeData",method = RequestMethod.GET) 应使用 http://www.example.com/api/getEmployeeData 访问。如果我们使用http://www.example.com/api/getemployeedata,我们会得到404错误。

          注意: http://www.example.com 仅供参考,我在上面提到过。它应该是您托管应用程序的域名。

          经过一番努力并应用了这篇文章中的所有其他答案,我发现问题仅在于该网址。这可能是个愚蠢的问题。但这花了我2个小时。所以我希望它会对某人有所帮助。

          【讨论】:

          • 一个好的做法是在 REST URL 中使用 spin-case 而不是 CamelCase。
          【解决方案13】:

          如果我们如下使用它也可以:

          @SpringBootApplication(scanBasePackages = { "<class ItemInventoryController package >.*" })
          

          【讨论】:

            【解决方案14】:

            可能是其他东西在端口 8080 上运行,而您实际上是错误地连接到它。

            一定要检查一下,特别是如果您的 docker 正在启动您无法控制的其他服务,并且正在端口转发这些服务。

            【讨论】:

              【解决方案15】:

              问题在于您的包结构。 Spring Boot Application 具有特定的包结构,以允许 Spring 上下文在其上下文中扫描和加载各种 bean。

              在 com.nice.application 中是您的主类所在的位置,在 com.nice.controller 中,您有您的控制器类。

              将您的 com.nice.controller 包移动到 com.nice.application 中,以便 Spring 可以访问您的 bean。

              【讨论】:

                【解决方案16】:

                另一个解决方案以防万一:就我而言,问题是我在类级别(在我的控制器中)有一个@RequestMapping("/xxx"),而在暴露的服务中我有@PostMapping (value = "/yyyy")@GetMapping (value = "/zzz");一旦我评论了@RequestMapping("/xxx") 并在方法级别管理所有内容,就像一个魅力。

                【讨论】:

                  【解决方案17】:

                  对我来说,问题在于我设置的应用程序总是在启动后立即关闭。因此,当我尝试是否可以访问控制器时,应用程序已不再运行。 立即关闭的问题在this thread 中解决。

                  【讨论】:

                    【解决方案18】:

                    将返回类型从 String 更改为 ResponseEntity

                    Like : 
                    @RequestMapping( "/item" )
                    public ResponseEntity<String> getStockItem() {
                            return new ResponseEntity<String>("It's working...!", HttpStatus.OK);
                    }
                    

                    【讨论】:

                      【解决方案19】:

                      @SpringBootApplication @ComponentScan(basePackages = {"com.rest"}) // basePackageClasses = HelloController.class) // 使用上面的组件扫描来添加包 公共类 RestfulWebServicesApplication {

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

                      }

                      【讨论】:

                        【解决方案20】:

                        将你的 springbootapplication 类放在根包中,例如,如果你的服务,控制器在 springBoot.xyz 包中,那么你的主类应该在 springBoot 包中,否则它不会扫描下面的包

                        【讨论】:

                          【解决方案21】:

                          您可以在 POM 中添加。

                          <dependency>
                              <groupId>org.springframework.boot</groupId>
                              <artifactId>spring-boot-configuration-processor</artifactId>
                              <version>XXXXXXXXX</version>
                          </dependency>
                          

                          【讨论】:

                            猜你喜欢
                            • 2019-09-30
                            • 2020-04-03
                            • 2021-03-23
                            • 2019-01-16
                            • 2017-03-12
                            • 2017-02-05
                            • 2016-12-21
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多