Spring Boot: Không thể truy cập Bộ điều khiển REST trên localhost (404)


104

Tôi đang cố gắng điều chỉnh ví dụ REST Controller trên trang web Spring Boot. Rất tiếc, tôi đã gặp lỗi sau khi cố gắng truy cập 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>

Starter-Application:

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-Bộ điều khiển:

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

}

Tôi đang xây dựng dự án này với Maven. Khởi động nó dưới dạng jar (spring-boot: run) và cũng như bên trong IDE (Eclipse).

Nhật ký bảng điều khiển:

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

Những gì tôi đã thử cho đến nay:

  • Truy cập URL có tên ứng dụng (InventoryApp)
  • Đặt một cái khác @RequestMapping("/")ở cấp lớp củaItemInventoryController

Theo như tôi hiểu, tôi sẽ không cần ngữ cảnh ứng dụng khi sử dụng Spring Boot. Tôi nói đúng chứ?

Tôi có thể làm gì khác để truy cập phương thức qua URL?


Bạn đang chạy ứng dụng như thế nào? Bạn có thể bao gồm một số bản ghi?
wjans

Đã thử nó riêng lẻ qua Eclipse và với mvn spring-boot: run (as jar). Xem ở trên để biết nhật ký (đã chỉnh sửa)
mchlfchr

Từ nhật ký khởi động, có vẻ như nó không tìm thấy bộ điều khiển của bạn, gói bộ điều khiển của bạn nằm trong gói nào?
MattR

1
Nó nằm trong một gói riêng biệt. Lớp khởi động với phương thức chính nằm trong "ứng dụng" trong khi bộ điều khiển nằm trong gói "bộ điều khiển". Tôi đã xem các ví dụ (không phải ví dụ trên spring.io), cũng được cấu trúc theo cách đó.
mchlfchr

4
Theo mặc định, spring-boot sẽ quét các thành phần trong cùng một gói hoặc các gói "bên dưới" (cùng tiền tố) với lớp ứng dụng của bạn. Nếu không, bạn cần phải quét một cách rõ ràng cho họ, ví dụ như sử dụng @ComponentScan
MattR

Câu trả lời:


197

Hãy thử thêm phần sau vào lớp InventoryApp của bạn

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

spring-boot sẽ quét các thành phần trong các gói bên dưới com.nice.application, vì vậy nếu bộ điều khiển của bạn có trong đó, com.nice.controllerbạn cần phải quét nó một cách rõ ràng.


Tôi có những vấn đề tương tự. Tôi cố gắng với componentscan nhưng không :-( câu hỏi Hier tôi: stackoverflow.com/questions/33000931/...
emoleumassi

1
xin lưu ý rằng @SpringBootApplicationbao gồm@Configuration
krzakov

9
Có vẻ dễ dàng nhất là đặt Ứng dụng trong gói "gốc", ví dụ: "org.w Anything" và các bộ điều khiển, dịch vụ trong gói con.
insan-e

7
Tôi có cùng một vấn đề nhưng trước khi đến với giải pháp này, tôi đã tìm thấy nó ... Thêm nữa. mất mùa xuân lớp ứng dụng khởi động của bạn (trong đó phương pháp chính được xác định) một mức độ lên đến gói điều khiển .. sau đó điều khiển sẽ hiển thị cho này và sẽ làm việc
Tayab Hussain

1
Bạn cũng có thể sử dụng '@ComponentScan (basePackages = "com.nice.controller")'. Quét mặc định thành phần bắt đầu trên đường dẫn, ở đó là lớp Ứng dụng và quét cả các gói phụ. Trong trường hợp đó, bạn không cần sử dụng chú thích @ComponentScan. Nó tự động. Nếu bạn có nhiều hơn 1 bộ điều khiển, bạn cũng có thể có chúng trong các gói khác nhau, bạn có thể xâu chuỗi chúng. Trong trường hợp đó, điều quan trọng là tránh xung đột.
hariprasad

47

Thêm vào câu trả lời của MattR:

Như đã nêu trong đây , @SpringBootApplicationsẽ tự động chèn các chú thích cần thiết: @Configuration, @EnableAutoConfiguration, và cũng có thể @ComponentScan; tuy nhiên, @ComponentScansẽ chỉ tìm kiếm các thành phần trong cùng một gói với Ứng dụng, trong trường hợp này là của bạn com.nice.application, trong khi bộ điều khiển của bạn nằm trong com.nice.controller. Đó là lý do tại sao bạn nhận được 404 vì Ứng dụng không tìm thấy bộ điều khiển trong applicationgói.


5
Trong trường hợp điều này chưa hoàn toàn rõ ràng so với giải thích ở trên, thì lớp có chú thích @SpringBootApplication phải ở TRÊN hoặc cùng cấp trong cấu trúc thư mục của bạn với những thứ bạn muốn nó tìm thấy. Ví dụ: tôi có com.app.configuration và com.app.controllers. Tôi đã đặt nhầm lớp Ứng dụng của mình vào com.app.configuration và mọi thứ khác trong com.app.configuration đều hoạt động tốt, nhưng không có gì trong com.app.controllers được tải. Tôi đã chuyển lớp Ứng dụng của mình sang com.app và các hạt đậu ở nơi khác đã được tìm thấy và mọi thứ bắt đầu hoạt động. Sai lầm của tân binh đối với tôi.
glaukommatos

2
Thêm @ComponentScan (basePackages = "com.base.package") giải quyết nó trong trường hợp của tôi
Shamli

Điều này thực sự hữu ích.
Madhu Tomy

12

Các nhà phát triển SpringBoot khuyên bạn nên định vị lớp ứng dụng chính của bạn trong gói gốc bên trên các lớp khác. Sử dụng gói gốc cũng cho phép sử dụng chú thích @ComponentScan mà không cần chỉ định thuộc tính basePackage . Thông tin chi tiết Nhưng hãy chắc chắn rằng gói gốc tùy chỉnh tồn tại.


10

Tôi nhận được cùng một phản hồi 404 sau khi dịch vụ được thực thi với mã dưới đây

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

}

Phản ứng:

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

sau khi thay đổi nó thành mã bên dưới, tôi đã nhận được phản hồi thích hợp

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

}

Phản ứng:

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

1
Trong trường hợp những người đọc khác không nhìn thấy nó, @Controller->@RestController
Janac Meena

7

Tôi gặp sự cố này và những gì bạn cần làm là sửa các gói của mình. Nếu bạn đã tải xuống dự án này từ http://start.spring.io/ thì bạn có lớp chính của mình trong một số gói. Ví dụ: nếu gói cho lớp chính là: "com.example" thì và bộ điều khiển của bạn phải nằm trong gói: "com.example.controller". Hi vọng điêu nay co ich.


6

Có 2 phương pháp để khắc phục điều này

  1. Đặt ứng dụng khởi động ở đầu cấu trúc gói và đặt tất cả bộ điều khiển bên trong nó.

    Thí dụ :

    gói com.spring.boot.app; - Ứng dụng khởi động của bạn (tức là Phương pháp chính -SpringApplication.run (App.class, args);)

    Bạn Rest Controller trong cùng một cấu trúc gói Ví dụ: package com.spring.boot.app.rest;

  2. Xác định rõ ràng Bộ điều khiển trong gói Khởi động.

Cách 1 sạch hơn.


1
khởi động mùa xuân ghét lớp ứng dụng là theo một số gói khác hơn là cơ sở package..if gói cơ bản là org.someapp và nếu chúng ta đặt nó dưới org.someapp.app nó bom ..: - /
Priyank Thakkar

3

Bạn cần sửa đổi lớp Starter-Application như hình dưới đây.

@SpringBootApplication

@EnableAutoConfiguration

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

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

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

Và cập nhật cấu trúc gói Controller, Service và Repository như tôi đã đề cập bên dưới.

Ví dụ: REST-Controller

package com.nice.controller; -> Nó phải được sửa đổi thành
package com.nice.application.controller;

Bạn cần tuân theo cấu trúc gói phù hợp cho tất cả các gói nằm trong luồng MVC Spring Boot.

Vì vậy, nếu bạn sửa đổi cấu trúc gói gói dự án của mình một cách chính xác thì ứng dụng khởi động mùa xuân của bạn sẽ hoạt động chính xác.


3
EnableAutoConfiguration được bao gồm trong @SpringBootApplication nên việc thêm nó vào là vô ích.
Sofiane,

1

Thay thế @RequestMapping( "/item" )bằng @GetMapping(value="/item", produces=MediaType.APPLICATION_JSON_VALUE).

Có thể nó sẽ giúp ích cho ai đó.


1
nó giúp tôi nhận ra rằng tôi đã viết namethay vì valuetrong @GetMapping.
vortex.alex

0

Tôi đã gặp chính xác lỗi tương tự, tôi không đưa ra gói cơ sở. Đưa ra gói cơ sở chính xác, giải quyết lại nó.

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

}

Lưu ý: không bao gồm .controller @ComponentScan (basePackages = "com.ymc.backend.controller") vì tôi có nhiều lớp thành phần khác mà dự án của tôi không quét nếu tôi chỉ cung cấp .controller

Đây là mẫu bộ điều khiển của tôi:

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

Đôi khi khởi động mùa xuân hoạt động kỳ lạ. Tôi đã chỉ định bên dưới trong lớp ứng dụng và nó hoạt động:

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

0

Tôi gặp sự cố 404 do Độ nhạy chữ hoa chữ thường Url .

Ví dụ @RequestMapping(value = "/api/getEmployeeData",method = RequestMethod.GET)nên được truy cập bằng cách sử dụng http://www.example.com/api/getEmployeeData. Nếu chúng tôi đang sử dụng http://www.example.com/api/getemployeedata, chúng tôi sẽ gặp lỗi 404.

Lưu ý: http://www.example.comchỉ để tham khảo mà tôi đã đề cập ở trên. Nó phải là tên miền của bạn nơi bạn lưu trữ ứng dụng của mình.

Sau rất nhiều đấu tranh và áp dụng tất cả các câu trả lời khác trong bài đăng này, tôi nhận ra rằng vấn đề chỉ là với url đó. Nó có thể là một vấn đề ngớ ngẩn. Nhưng nó tiêu tốn 2 giờ của tôi. Vì vậy, tôi hy vọng nó sẽ giúp một ai đó.


0

đối với tôi, tôi đã thêm spring-web thay vì spring-boot-starter-web vào pom.xml của mình

khi tôi thay thế nó từ spring-web thành spring-boot-starter-web, tất cả ánh xạ được hiển thị trong nhật ký bảng điều khiển.


0

Nó cũng hoạt động nếu chúng ta sử dụng như sau:

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

0

Có thể có thứ gì đó khác đang chạy trên cổng 8080 và bạn thực sự đang kết nối nhầm với nó.

Chắc chắn hãy kiểm tra điều đó, đặc biệt nếu bạn có dockers đang cung cấp các dịch vụ khác mà bạn không kiểm soát và đang chuyển tiếp các dịch vụ đó.


0

Vấn đề là với cấu trúc gói của bạn. Ứng dụng Spring Boot có cấu trúc gói cụ thể để cho phép ngữ cảnh mùa xuân quét và tải các bean khác nhau trong ngữ cảnh của nó.

Trong com.nice.application là nơi có Lớp chính của bạn và trong com.nice.controller, bạn có các lớp điều khiển của mình.

Di chuyển gói com.nice.controller của bạn vào com.nice.application để Spring có thể truy cập các bean của bạn.


-1

Bạn có thể thêm vào bên trong POM.

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

-2

Đặt lớp ứng dụng springboot của bạn trong gói gốc, ví dụ nếu dịch vụ, bộ điều khiển của bạn nằm trong gói springBoot.xyz thì lớp chính của bạn phải nằm trong gói springBoot nếu không nó sẽ không quét các gói bên dưới

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.