Spring Boot: impossibile accedere al controller REST su localhost (404)


104

Sto cercando di adattare l'esempio del controller REST sul sito Web di Spring Boot. Sfortunatamente ricevo il seguente errore quando provo ad accedere localhost:8080/itemall'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 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-Applicazione:

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-Controller:

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

}

Sto costruendo questo progetto con Maven. Avviato come jar (spring-boot: run) e anche all'interno dell'IDE (Eclipse).

Registro della console:

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

Quello che ho provato finora:

  • Accesso all'URL con il nome dell'applicazione (InventoryApp)
  • Mettine un altro @RequestMapping("/")a livello di classe diItemInventoryController

Per quanto ho capito, non avrò bisogno di un contesto dell'applicazione quando utilizzo Spring Boot. Ho ragione?

Cos'altro posso fare per accedere al metodo tramite URL?


Come stai eseguendo l'applicazione? Puoi forse includere alcuni log?
wjans

Ho provato separatamente tramite Eclipse e con mvn spring-boot: run (as jar). Vedi sopra per i log (modificati)
mchlfchr

Dal registro di avvio non sembra che stia trovando il tuo controller, in quale pacchetto si trova la tua classe controller?
MattR

1
È in un pacchetto separato. La classe di avviamento con il metodo principale è in "application" mentre il controller è nel pacchetto "controller". Ho visto esempi (non quelli su spring.io), anch'essi strutturati in quel modo.
mchlfchr

4
Per impostazione predefinita, spring-boot cercherà i componenti nello stesso pacchetto o pacchetti "sotto" (stesso prefisso) della classe dell'applicazione. Altrimenti è necessario scansionarli esplicitamente, ad esempio utilizzando @ComponentScan
MattR

Risposte:


197

Prova ad aggiungere quanto segue alla tua classe InventoryApp

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

spring-boot cercherà i componenti nei pacchetti sottostanti com.nice.application, quindi se il tuo controller è in com.nice.controllerdevi cercarlo esplicitamente.


Ho gli stessi problemi. Provo con la componentscan ma niente :-( Hier la mia domanda: stackoverflow.com/questions/33000931/...
emoleumassi

1
si prega di notare che @SpringBootApplicationinclude@Configuration
krzakov

9
Sembra più facile mettere l'applicazione nel pacchetto "root", ad esempio "org.wwhat" e i controller, i servizi in sottopacchetti.
insan-e

7
Ho lo stesso problema ma prima di arrivare a questa soluzione l'ho trovata ... Altro ancora. prendi la tua classe di applicazione di avvio primaverile (in cui è definito il metodo principale) un livello fino al pacchetto del controller .. quindi i controller saranno visibili a questo e funzioneranno
Tayab Hussain

1
Puoi anche utilizzare "@ComponentScan (basePackages =" com.nice.controller ")". La scansione predefinita del componente inizia nel percorso, dove si trova la classe App e analizza anche i pacchetti sussidiari. In tal caso non è necessario utilizzare l'annotazione @ComponentScan. Lo fa automaticamente. Se hai più di 1 controller, è possibile averli anche in pacchetti diversi, puoi concatenarli. In tal caso è importante evitare conflitti.
hariprasad

47

Aggiungendo alla risposta di mattr:

Come indicato nel qui , @SpringBootApplicationinserisce automaticamente le annotazioni necessarie: @Configuration, @EnableAutoConfiguration, e anche @ComponentScan; tuttavia, @ComponentScancercherà solo i componenti nello stesso pacchetto dell'App, in questo caso il tuo com.nice.application, mentre il tuo controller risiede com.nice.controller. Ecco perché ottieni 404 perché l'app non ha trovato il controller nel applicationpacchetto.


5
Nel caso in cui ciò non sia completamente chiaro già dalla spiegazione sopra, la classe con l'annotazione @SpringBootApplication deve essere SOPRA o allo stesso livello nella struttura della directory delle cose che vorresti che trovasse. Ad esempio, avevo com.app.configuration e com.app.controllers. Ho erroneamente inserito la mia classe Application in com.app.configuration e tutto il resto in com.app.configuration ha funzionato bene, ma non veniva caricato nulla in com.app.controllers. Ho spostato la mia classe Application in com.app, i bean sono stati trovati altrove e le cose hanno iniziato a funzionare. Errore da principiante per me.
glaukommatos

2
L'aggiunta di @ComponentScan (basePackages = "com.base.package") ha risolto il problema nel mio caso
Shamli

Questo aiuta davvero.
Madhu Tomy

12

Gli sviluppatori di SpringBoot consigliano di individuare la classe dell'applicazione principale in un pacchetto root sopra le altre classi. L'utilizzo di un pacchetto radice consente inoltre di utilizzare l'annotazione @ComponentScan senza la necessità di specificare un attributo basePackage . Informazioni dettagliate Ma assicurati che esista il pacchetto root personalizzato.


10

Stessa risposta 404 che ho ricevuto dopo che il servizio è stato eseguito con il codice seguente

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

}

Risposta:

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

dopo averlo modificato nel codice sottostante, ho ricevuto una risposta adeguata

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

}

Risposta:

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

1
Nel caso in cui altri lettori non lo vedano, @Controller->@RestController
Janac Meena il

7

Ho avuto questo problema e quello che devi fare è riparare i tuoi pacchetti. Se hai scaricato questo progetto da http://start.spring.io/, allora hai la tua classe principale in qualche pacchetto. Ad esempio, se il pacchetto per la classe principale è: "com.example", e il controller deve essere nel pacchetto: "com.example.controller". Spero che questo ti aiuti.


6

Esistono 2 metodi per superare questo problema

  1. Posiziona l'applicazione di avvio all'inizio della struttura del pacchetto e posiziona tutti i controller al suo interno.

    Esempio :

    pacchetto com.spring.boot.app; - La tua applicazione di avvio (cioè il metodo principale -SpringApplication.run (App.class, args);)

    Resta il controller con la stessa struttura del pacchetto Esempio: pacchetto com.spring.boot.app.rest;

  2. Definisci esplicitamente il controller nel pacchetto Bootup.

Il metodo 1 è più pulito.


1
spring boot odia che la classe dell'applicazione si trovi in ​​un pacchetto diverso dal pacchetto base..se il pacchetto base è org.someapp e se lo mettiamo sotto org.someapp.app bombarda ..: - /
Priyank Thakkar

3

È necessario modificare la classe Starter-Application come mostrato di seguito.

@SpringBootApplication

@EnableAutoConfiguration

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

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

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

E aggiorna la struttura dei pacchetti controller, servizio e repository come ho menzionato di seguito.

Esempio: REST-Controller

package com.nice.controller; -> Deve essere modificato come
package com.nice.application.controller;

È necessario seguire la struttura del pacchetto corretta per tutti i pacchetti che si trovano nel flusso Spring Boot MVC.

Quindi, se modifichi correttamente le strutture del pacchetto del bundle del progetto, l'app di avvio primaverile funzionerà correttamente.


3
EnableAutoConfiguration è incluso in @SpringBootApplication quindi è inutile aggiungerlo.
Sofiane

1

Sostituisci @RequestMapping( "/item" )con @GetMapping(value="/item", produces=MediaType.APPLICATION_JSON_VALUE).

Forse aiuterà qualcuno.


1
mi ha aiutato a riconoscere che avevo scritto nameinvece che valuein @GetMapping.
vortex.alex

0

Ho avuto lo stesso errore, non stavo dando il pacchetto di base. Dando il pacchetto base corretto, risolto.

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

}

Nota: non includendo .controller @ComponentScan (basePackages = "com.ymc.backend.controller") perché ho molte altre classi di componenti che il mio progetto non analizza se fornisco solo .controller

Ecco il mio esempio di 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

A volte lo stivale primaverile si comporta in modo strano. Ho specificato di seguito nella classe dell'applicazione e funziona:

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

0

Ho avuto il problema 404, a causa della sensibilità tra maiuscole e minuscole URL .

Ad esempio, @RequestMapping(value = "/api/getEmployeeData",method = RequestMethod.GET)dovrebbe essere accessibile utilizzando http://www.example.com/api/getEmployeeData. Se stiamo usandohttp://www.example.com/api/getemployeedata , otterremo l'errore 404.

Nota: http://www.example.comè solo per riferimento che ho menzionato sopra. Dovrebbe essere il nome del tuo dominio in cui hai ospitato la tua applicazione.

Dopo un sacco di fatica e applicato tutte le altre risposte in questo post, ho capito che il problema è solo con quell'URL. Potrebbe essere un problema stupido. Ma mi è costato 2 ore. Quindi spero che possa aiutare qualcuno.


0

per me, stavo aggiungendo spring-web invece di spring-boot-starter-web nel mio pom.xml

quando lo sostituisco da spring-web a spring-boot-starter-web, tutta la mappatura viene mostrata nel registro della console.


0

Funziona anche se usiamo come segue:

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

0

Potrebbe essere che qualcos'altro sia in esecuzione sulla porta 8080 e che ti stai effettivamente connettendo per errore.

Sicuramente controllalo, specialmente se hai docker che stanno portando altri servizi che non controlli e stanno eseguendo il port forwarding di quei servizi.


0

Il problema è con la struttura del tuo pacchetto. Spring Boot Application ha una struttura di pacchetti specifica per consentire al contesto spring di scansionare e caricare vari bean nel suo contesto.

In com.nice.application è dove si trova la tua classe principale e in com.nice.controller, hai le classi del controller.

Sposta il tuo pacchetto com.nice.controller in com.nice.application in modo che Spring possa accedere ai tuoi bean.


-1

Puoi aggiungere all'interno del POM.

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

-2

Posiziona la tua classe springbootapplication nel pacchetto root, ad esempio se il tuo servizio, il controller è nel pacchetto springBoot.xyz, la tua classe principale dovrebbe essere nel pacchetto springBoot altrimenti non scansionerà i pacchetti sottostanti

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.