Spring Boot : localhost에서 REST 컨트롤러에 액세스 할 수 없음 (404)


105

Spring Boot 웹 사이트에서 REST 컨트롤러 예제를 적용하려고합니다. 불행히도 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

시작 로그에서 컨트롤러를 찾는 것처럼 보이지 않습니다. 컨트롤러 클래스는 어떤 패키지에 있습니까?
MattR

1
별도의 패키지에 있습니다. main 메소드가있는 스타터 클래스는 "application"에 있고 컨트롤러는 "controller"패키지에 있습니다. 나는 예제 (spring.io의 예제가 아님)를 보았습니다. 이것 역시 그런 방식으로 구성되었습니다.
mchlfchr

4
기본적으로 spring-boot는 동일한 패키지의 구성 요소 또는 애플리케이션 클래스와 "아래"(동일한 접두사) 패키지를 검색합니다. 그렇지 않으면 당신은 명시 적으로 검사 할 필요가, 예를 들면 @ComponentScan 사용
MattR

답변:


198

InventoryApp 클래스에 다음을 추가해보십시오.

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

spring-boot는 아래 패키지의 구성 요소를 스캔 com.nice.application하므로 컨트롤러가있는 com.nice.controller경우 명시 적으로 스캔해야합니다.


나도 같은 문제가 있습니다. 나는 componentscan으로 시도하지만 아무것도 :-( Hier my question : stackoverflow.com/questions/33000931/…
emoleumassi

1
제발 노트 @SpringBootApplication포함@Configuration
krzakov

9
응용 프로그램을 "루트"패키지 (예 : "org.whatever")에 넣고 컨트롤러, 서비스를 하위 패키지에 넣는 것이 가장 쉬운 것 같습니다.
insan-e

7
나는 같은 문제가 있지만이 솔루션에 오기 전에 나는 그것을 발견했다 ... 더 이상. 컨트롤러 패키지에 한 단계 업 .. 다음 컨트롤러는이에 볼 수와 작동합니다 (main 메소드가 정의 된) 봄 부팅 응용 프로그램의 수업을
Tayab 후세인

1
'@ComponentScan (basePackages = "com.nice.controller")'를 사용할 수도 있습니다. 구성 요소 기본 스캔은 경로에서 시작됩니다. 여기서는 앱 클래스이고 보조 패키지도 스캔합니다. 이 경우 @ComponentScan 주석을 사용할 필요가 없습니다. 자동으로 수행됩니다. 컨트롤러가 2 개 이상인 경우 다른 패키지에도 포함 할 수 있으며 연결할 수 있습니다. 이 경우 충돌을 피하는 것이 중요합니다.
hariprasad

48

MattR의 대답에 추가 :

에 명시된 바와 같이 여기 , @SpringBootApplication자동으로 필요한 주석을 삽입합니다 @Configuration, @EnableAutoConfiguration또한,와 @ComponentScan; 그러나은 @ComponentScan앱과 동일한 패키지에있는 구성 요소 만 찾습니다.이 경우 com.nice.application컨트롤러는 com.nice.controller. 앱이 application패키지 에서 컨트롤러를 찾지 못했기 때문에 404가 표시되는 이유 입니다.


5
위의 설명에서 이미 완전히 명확하지 않은 경우 @SpringBootApplication 주석이있는 클래스는 디렉토리 구조에서 찾고자하는 것과 같은 수준이거나 위 여야합니다. 예를 들어 com.app.configuration 및 com.app.controllers가 있습니다. 실수로 내 Application 클래스를 com.app.configuration에 넣었고 com.app.configuration의 다른 모든 것이 제대로 작동했지만 com.app.controllers에는 아무것도로드되지 않았습니다. 내 Application 클래스를 com.app으로 옮겼고 다른 곳에서 빈이 발견되었고 일이 시작되었습니다. 나를위한 신인 실수.
glaukommatos

2
@ComponentScan 추가 (basePackages을 = "com.base.package")는 내 경우에는 그것을 해결
Shamli

이것은 정말 도움이됩니다.
Madhu Tomy

12

SpringBoot 개발자는 다른 클래스 위의 루트 패키지에서 기본 애플리케이션 클래스를 찾을 것을 권장합니다. 루트 패키지를 사용하면 basePackage 속성 을 지정하지 않고도 @ComponentScan 주석을 사용할 수 있습니다 . 자세한 정보 그러나 사용자 지정 루트 패키지가 있는지 확인하십시오.


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
대비하여

7

이 문제가 발생했으며 패키지를 수정해야합니다. http://start.spring.io/ 에서이 프로젝트를 다운로드 한 경우 일부 패키지에 기본 클래스가 있습니다. 예를 들어 기본 클래스의 패키지가 "com.example"이면 컨트롤러가 "com.example.controller"패키지에 있어야합니다. 도움이 되었기를 바랍니다.


6

이를 극복하는 방법은 2 가지가 있습니다.

  1. 패키지 구조의 시작 부분에 부팅 응용 프로그램을 배치하고 그 안에 모든 컨트롤러를 놓습니다.

    예 :

    패키지 com.spring.boot.app; -응용 프로그램을 부팅합니다 (예 : Main Method -SpringApplication.run (App.class, args);).

    동일한 패키지 구조로 컨트롤러를 나머지 예 : package com.spring.boot.app.rest;

  2. Bootup 패키지에서 컨트롤러를 명시 적으로 정의합니다.

방법 1이 더 깨끗합니다.


1
스프링 부트는 기본 패키지가 아닌 다른 패키지 아래에있는 응용 프로그램 클래스를 싫어합니다. 기본 패키지가 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 {..........

그리고 아래에서 언급 한대로 컨트롤러, 서비스 및 리포지토리 패키지 구조를 업데이트합니다.

예 : REST 컨트롤러

package com.nice.controller; -> 다음과 같이 수정해야합니다.
package com.nice.application.controller;

Spring Boot MVC 흐름에있는 모든 패키지에 대해 적절한 패키지 구조를 따라야합니다.

따라서 프로젝트 번들 패키지 구조를 올바르게 수정하면 스프링 부트 앱이 올바르게 작동합니다.


3
EnableAutoConfiguration은 @SpringBootApplication에 포함되어 있으므로 추가 할 필요가 없습니다.
Sofiane

1

교체 @RequestMapping( "/item" )와 함께 @GetMapping(value="/item", produces=MediaType.APPLICATION_JSON_VALUE).

누군가에게 도움이 될 수도 있습니다.


1
그것은 나를 내가 쓴 것을 인식하는 데 도움이 name대신 value에서 @GetMapping.
vortex.alex

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를 제공하면 내 프로젝트가 스캔하지 않는 다른 많은 구성 요소 클래스가 있기 때문에 .controller @ComponentScan (basePackages = "com.ymc.backend.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

Url Case Sensitivity 때문에 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-boot-starter-web 대신 spring-web을 pom.xml에 추가했습니다.

spring-web에서 spring-boot-starter-web으로 바꾸면 모든 매핑이 콘솔 로그에 표시됩니다.


0

다음과 같이 사용하는 경우에도 작동합니다.

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

0

포트 8080에서 다른 것이 실행 중일 수 있으며 실제로 실수로 연결하고있을 수 있습니다.

특히 제어하지 않는 다른 서비스를 가져오고 해당 서비스를 포트 포워딩하는도 커가있는 경우 확실히 확인하십시오.


0

문제는 패키지 구조에 있습니다. Spring Boot Application은 Spring 컨텍스트가 컨텍스트에서 다양한 Bean을 스캔하고로드 할 수 있도록 특정 패키지 구조를 가지고 있습니다.

com.nice.application에서는 메인 클래스가 있고 com.nice.controller에는 컨트롤러 클래스가 있습니다.

Spring이 Bean에 액세스 할 수 있도록 com.nice.controller 패키지를 com.nice.application으로 이동하십시오.


-1

POM 내부에 추가 할 수 있습니다.

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

-2

예를 들어 서비스, 컨트롤러가 springBoot.xyz 패키지에있는 경우 springbootapplication 클래스를 루트 패키지에 배치하고 메인 클래스는 springBoot 패키지에 있어야합니다. 그렇지 않으면 패키지 아래를 스캔하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.