Spring Boot:无法访问localhost上的REST控制器(404)

时间:2015-07-09 12:52:33

标签: java rest spring-boot

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

{
  "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时我不需要应用程序上下文。我是对的吗?

我还可以通过网址访问该方法吗?

21 个答案:

答案 0 :(得分:133)

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

$scope.loadData = function () {
    $scope.loaded = false;
    dataFactory.getData($scope.RecordId)
    .$promise
    .then(function (resp) {
        $scope.Data = resp;
        $scope.loaded = true;
    }, function (resp) {
        $scope.loaded = true;
        $scope.handleResourceError(resp);
    })
};

spring-boot将扫描@SpringBootApplication @ComponentScan(basePackageClasses = ItemInventoryController.class) public class InventoryApp { ... 下方包中的组件,因此如果您的控制器位于com.nice.application,则需要明确扫描。

答案 1 :(得分:36)

添加到MattR的答案:

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

答案 2 :(得分:8)

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

答案 3 :(得分:5)

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

答案 4 :(得分:4)

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

方法1)将启动应用程序放在包结构的开头,并将所有控制器放在其中 示例: package com.spring.boot.app; - 你的启动应用程序(即主要方法-SpringApplication.run(App.class,args);)

您使用相同的包结构来控制Controller 示例: 包com.spring.boot.app.rest;

方法2)在Bootup包中明确定义Controller。

方法1更清洁。

希望这会有所帮助。

答案 5 :(得分:4)

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

答案 6 :(得分:1)

您需要修改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; - &gt;它必须修改为
package com.nice.application.controller;

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

因此,如果您正确修改项目包包结构,那么您的春季启动应用程序将正常工作。

答案 7 :(得分: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";
    };


}

答案 8 :(得分:0)

将返回类型从 String 更改为 ResponseEntity

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

答案 9 :(得分:0)

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

答案 10 :(得分:0)

在有帮助的情况下的另一种解决方案:就我而言,问题是我在班级(在我的控制器中)有一个@RequestMapping("/xxx"),在公开服务中我有@PostMapping (value = "/yyyy")和{{ 1}};一旦我评论了@GetMapping (value = "/zzz")并在方法级别进行了全部管理,就像魅力一样。

答案 11 :(得分:0)

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

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

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

答案 12 :(得分:0)

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

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

答案 13 :(得分:0)

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

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

答案 14 :(得分:0)

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

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

答案 15 :(得分:0)

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

例如 应该使用G = graph(adj); for k = 1:G.numnodes disp(G.dfsearch(k)); end 访问@RequestMapping(value = "/api/getEmployeeData",method = RequestMethod.GET)。如果使用http://www.example.com/api/getEmployeeData,则会收到404错误。

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

经过艰苦的努力,并在这篇文章中应用了所有其他答案之后,我才知道问题仅在于该URL。这可能是愚蠢的问题。但这花了我两个小时。所以我希望它能对某人有所帮助。

答案 16 :(得分:0)

有时,弹簧靴的行为很奇怪。我在下面的应用程序类中指定了它,并且有效:

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

答案 17 :(得分:0)

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

也许它会帮助某人。

答案 18 :(得分:-1)

您可以在POM中添加

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

答案 19 :(得分:-2)

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

答案 20 :(得分:-11)

您的网址应该是,您缺少应用程序上下文: 本地主机:8080 / SpringBootTest /项目