Spring Boot:无法访问localhost上的REST Controller(404)


104

我正在尝试在Spring Boot网站上改编REST Controller示例。不幸的是,当我尝试访问localhost:8080/itemURL 时遇到以下错误。

{
  "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 its 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访问该方法吗?


您如何运行该应用程序?您可以包括一些日志吗?
wjans

通过Eclipse和mvn spring-boot:run(以jar形式)分别进行了尝试。参见上面的日志(已编辑)
mchlfchr 2015年

从启动日志中似乎找不到控制器,您的控制器类在哪个包中?
MattR

1
在单独的包装中。带有main方法的启动程序类位于“应用程序”中,而控制器位于程序包“ controller”中。我看过示例(不是spring.io上的示例),这些示例也是以这种方式构造的。
mchlfchr 2015年

4
默认情况下,spring-boot将扫描与您的应用程序类相同的软件包或“以下”(前缀相同)的软件包。否则,您需要显式扫描它们,例如,使用@ComponentScan
MattR 2015年

Answers:


196

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

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

spring-boot将扫描以下软件包中的组件com.nice.application,因此,如果您的控制器位于其中,则com.nice.controller需要进行显式扫描。


我有同样的问题。我尝试用componentscan但没有:-(海尔我的问题:stackoverflow.com/questions/33000931/...
emoleumassi

1
请注意,@SpringBootApplication其中包括@Configuration
krzakov 2015年

9
将应用程序放在“根”包中似乎是最容易的,例如将“ org.whatever”和控制器服务放在子包中。
insan-e

7
我有同样的问题,但是在找到这个解决方案之前,我发现了...更多。将您的spring boot应用程序类(在其中定义了main方法的类)带到控制器软件包的上一级。然后控制器将对此可见并且将起作用
Tayab Hussain

1
您也可以使用'@ComponentScan(basePackages =“ com.nice.controller”)'。组件默认扫描从路径开始,该路径是App类,还扫描子程序包。在这种情况下,您无需使用@ComponentScan批注。它会自动执行。如果您有多个控制器,则也可以将它们包装在不同的包装中,您可以将它们链接起来。在这种情况下,避免冲突很重要。
hariprasad

46

添加到将mattr的回答是:

由于在规定位置@SpringBootApplication会自动将所需的注释:@Configuration@EnableAutoConfiguration,和也@ComponentScan; 但是,@ComponentScan只会在与App相同的程序包中查找组件,在这种情况下,您的com.nice.application,而您的控制器位于中com.nice.controller。这就是为什么得到404的原因,因为该应用程序未在application包中找到控制器。


5
如果以上说明还不能完全弄清,带有@SpringBootApplication批注的类必须在目录结构之上或与您要查找的对象处于同一级别。例如,我有com.app.configuration和com.app.controllers。我错误地将我的Application类放入com.app.configuration中,并且com.app.configuration中的其他所有内容都正常运行,但是com.app.controllers中的任何内容均未加载。我将Application类移到com.app中,并找到了其他地方的bean,事情开始起作用。新秀对我来说是错误的。
glaukommatos

2
添加@ComponentScan(basePackages =“ com.base.package”)解决了我的问题
Shamli

这确实有帮助。
Madhu Tomy

12

SpringBoot开发人员建议将主应用程序类放在其他类之上的根包中。使用根包也可以使用@ComponentScan批注,而无需指定basePackage属性。 详细信息 但请确保自定义根软件包已存在。


10

使用以下代码执行服务后得到的相同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"
}

1
万一其他读者看不到, @Controller->@RestController
Janac Meena

7

我遇到了这个问题,您需要做的是修复软件包。如果您从http://start.spring.io/下载了该项目,则您的主类位于某个软件包中。例如,如果主类的程序包是:“ com.example”,则您的控制器必须在程序包中:“ com.example.controller”。希望这可以帮助。


6

有两种方法可以克服这个问题

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

    范例:

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

    您可以使用相同的程序包结构来休息Controller例子:package com.spring.boot.app.rest;

  2. 在启动包中明确定义Controller。

方法1更干净。


1
spring boot讨厌应用程序类位于基本软件包以外的某个软件包下。如果基本软件包是org.someapp,并且如果将其放在org.someapp.app下,则它会炸弹。:-/
Priyank Thakkar

3

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

@SpringBootApplication

@EnableAutoConfiguration

@ComponentScan(basePackages="com.nice.application")

@EnableJpaRepositories("com.spring.app.repository")

public class InventoryApp extends SpringBootServletInitializer {..........

并更新我下面提到的Controller,Service和Repository软件包结构。

示例:REST-Controller

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

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

因此,如果您正确地修改了项目捆绑包的结构,那么您的spring boot应用程序将正常运行。


3
EnableAutoConfiguration包含在@SpringBootApplication中,因此添加它毫无用处。
Sofiane


0

我有完全相同的错误,我没有给基本包。提供正确的基本包装,解决了。

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";
    };


}

0

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

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

0

由于网址区分大小写,我遇到了404问题。

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

注意: http://www.example.com以上仅供参考。它应该是您托管应用程序的域名。

经过大量的努力,并在本文中应用了所有其他答案,我才知道问题仅在于该URL。这可能是愚蠢的问题。但这花了我2个小时。因此,我希望它能对某人有所帮助。


0

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

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


0

如果我们使用以下方法,它也可以工作:

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

0

可能其他原因正在端口8080上运行,而您实际上是错误地连接到该端口。

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


0

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

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

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


-1

您可以在POM中添加。

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

-2

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.