2016-05-03 17 views
5

Próbuję zaimplementować prostą aplikację demonstracyjną MVC z Spring Boot, ale otrzymuję błąd 404 podczas wykonywania aplikacji. Uri to `http://localhost:8080/ ', który wyświetla wszystkie wiersze w tabeli o nazwie circle.Rest Controller nie rozpoznaje żądania GET w Spring Boot App

  • Wiosna Boot: 1.3.3.RELEASE
  • Java wersja: 1.8.0_65
  • Baza: Apache Derby 10.12.1.1

Maven Java projektu:

Maven Java Project Structure

Application.java

package com.nomad.dubbed.app; 

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 

@SpringBootApplication 
public class Application { 

    public static void main(String[] args){ 
     SpringApplication.run(Application.class, args); 
    } 

} 

CircleController.java

package com.nomad.dubbed.controller; 

import java.util.List; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RestController; 

import com.nomad.dubbed.dao.CircleService; 
import com.nomad.dubbed.model.Circle; 

@RestController 
@RequestMapping("/") 
public class CircleController { 
    @Autowired 
    private CircleService circleService; 

    @RequestMapping(method=RequestMethod.GET) 
    public List<Circle> getAll() { 
     return circleService.getAll(); 
    } 

} 

CircleRepository.java

package com.nomad.dubbed.dao; 

import org.springframework.data.jpa.repository.JpaRepository; 
import org.springframework.stereotype.Repository; 

import com.nomad.dubbed.model.Circle; 

@Repository 
public interface CircleRepository extends JpaRepository<Circle, Integer> { 

} 

CircleService.java

package com.nomad.dubbed.dao; 

import java.util.List; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Service; 
import org.springframework.transaction.annotation.Propagation; 
import org.springframework.transaction.annotation.Transactional; 

import com.nomad.dubbed.model.Circle; 

@Service 
public class CircleService { 
    @Autowired 
    private CircleRepository circleRepository; 

    @Transactional(propagation=Propagation.REQUIRED) 
    public List<Circle> getAll(){ 
     return circleRepository.findAll(); 
    } 

} 

Circle.java

package com.nomad.dubbed.model; 

import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.Table; 

@Entity 
@Table(name="circle") 
public class Circle { 
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int id; 
    private String name; 

    public Circle(int id, String name) { 
     super(); 
     this.id = id; 
     this.name = name; 
    } 

    public int getId() { 
     return id; 
    } 
    public void setId(int id) { 
     this.id = id; 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 

} 

application.properties

spring.datasource.url=jdbc:derby://localhost:1527/db 
spring.datasource.driverClassName=org.apache.derby.jdbc.ClientDriver 

logging.level.org.springframework.web:DEBUG 
logging.level.org.hibernate:DEBUG 

pom.xml

<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>com.nomad.dubbed</groupId> 
    <artifactId>spring-boot-mvc</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 


    <properties> 
     <derby-client.version>10.11.1.1</derby-client.version> 
    </properties> 

    <parent> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-parent</artifactId> 
     <version>1.3.3.RELEASE</version> 
     <relativePath /> 
    </parent> 
    <dependencies> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-web</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-actuator</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-remote-shell</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-data-jpa</artifactId> 
     </dependency> 

     <dependency> 
      <groupId>org.apache.derby</groupId> 
      <artifactId>derbyclient</artifactId> 
      <version>${derby-client.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <scope>test</scope> 
     </dependency> 
    </dependencies> 
    <build> 
     <finalName>spring-boot-mvc</finalName> 
     <plugins> 
      <plugin> 
       <groupId>org.springframework.boot</groupId> 
       <artifactId>spring-boot-maven-plugin</artifactId> 
      </plugin> 
     </plugins> 
    </build> 

</project> 

bazy danych jest uruchomiony i działa, istnieje 5 ro WS w kręgu tabeli:

enter image description here

Domyślna uri (/ fasola/zdrowie ..) działa dobrze, ale wdrożony kontroler nie jest rozpoznawany. Nie ma błędów takich wyświetlanych w konsoli, poniżej jest zrzut logów wydrukowanych w konsoli po wysłaniu żądania.

2016-05-03 14:17:26.594 DEBUG 659 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet  : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/] 
2016-05-03 14:17:26.596 DEBUG 659 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path/
2016-05-03 14:17:26.596 DEBUG 659 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/] 
2016-05-03 14:17:26.597 DEBUG 659 --- [nio-8080-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/] are [/**] 
2016-05-03 14:17:26.597 DEBUG 659 --- [nio-8080-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/] are {} 
2016-05-03 14:17:26.597 DEBUG 659 --- [nio-8080-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[[email protected]13019c]]] and 1 interceptor 
2016-05-03 14:17:26.597 DEBUG 659 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet  : Last-Modified value for [/] is: -1 
2016-05-03 14:17:26.597 DEBUG 659 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet  : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling 
2016-05-03 14:17:26.597 DEBUG 659 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet  : Successfully completed request 
2016-05-03 14:17:26.597 DEBUG 659 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet  : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error] 
2016-05-03 14:17:26.600 DEBUG 659 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error 
2016-05-03 14:17:26.600 DEBUG 659 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)] 
2016-05-03 14:17:26.600 DEBUG 659 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet  : Last-Modified value for [/error] is: -1 
2016-05-03 14:17:26.601 DEBUG 659 --- [nio-8080-exec-3] o.s.w.s.v.ContentNegotiatingViewResolver : Requested media types are [text/html, text/html;q=0.8] based on Accept header types and producible media types [text/html]) 
2016-05-03 14:17:26.601 DEBUG 659 --- [nio-8080-exec-3] o.s.w.s.v.ContentNegotiatingViewResolver : Returning [org.springfram[email protected]2f5f8d71] based on requested media type 'text/html' 
2016-05-03 14:17:26.601 DEBUG 659 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet  : Rendering view [org.springfram[email protected]2f5f8d71] in DispatcherServlet with name 'dispatcherServlet' 
2016-05-03 14:17:26.601 DEBUG 659 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet  : Successfully completed request 

Rest App Browser

+0

jaka jest twoja ścieżka aplikacji? – ACV

+2

Wykonaj mniejsze kroki. Niech getAll zwróci "cześć" na początku. –

Odpowiedz

11

użyć innego adresu URL dla kontrolera. "/" w mapach rozruchu sprężystego do zasobów statycznych zlokalizowanych w META-INF/resources i src/main/resources/static /.

edit: zapomnieć powyżej i wykonaj następujące czynności w swojej klasie aplikacji:

Application.java

package com.nomad.dubbed.app; 

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 

@SpringBootApplication 
@ComponentScan("com.nomad.dubbed") 
public class Application { 

    public static void main(String[] args){ 
     SpringApplication.run(Application.class, args); 
    } 

} 

kontroler reszta nie jest odkryta przez wiosenno-buty skanowania komponent. zgodnie z tym dokumentem http://docs.spring.io/spring-boot/docs/current/reference/html/ ... spring skanuje pakiety poniżej pakietu, w którym znajduje się klasa z adnotacją @SpringBootApplication. twój kontroler znajduje się w pakiecie równoległym.

+0

@Lume Zmieniłem go na '/ circles', ciągle ten sam błąd. '@RequestMapping (value = "/ kręgi" method = RequestMethod.GET, produkuje = { "application/json", "application/xml"}) \t @ResponseBody \t Lista publiczna getAll() {return \t \t circleService.getAll(); \t} ' – gkc123

+2

Cholera, dziwne. inna myśl: Spring-boot rejestruje wszystkie zmapowane adresy URL przy starcie. czy możesz też opublikować wiadomości z dziennika startowego? – lumue

+2

Myślę, że znalazłem twój problem: twój kontroler odpoczynku nie jest wykryty przez skanowanie skoku sprężynowego. zgodnie z tym dokumentem https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-structuring-your-code.html wiosna skanuje pakiety pod pakietem, gdzie klasa z Adnotacja @SpringBootApplication znajduje się. Twój kontroler znajduje się w pakiecie równoległym. – lumue

0

Można spróbować dodawania adnotacji @ResponseBody

@RequestMapping(method=RequestMethod.GET) 
@ResponseBody 
    public List<Circle> getAll() { 
     return circleService.getAll(); 
    } 
+0

Zmodyfikowałem kod zgodnie z sugestią, bez powodzenia. Nadal otrzymuję komunikat "Nie znaleziono metody obsługi dla błędu [/]". ścieżka jest aplikacja @ACV/'@RequestMapping (value = "/" method = RequestMethod.GET, produkuje = { "application/json", "application/xml"}) \t @ResponseBody \t Lista publiczna getAll() { \t \t return circleService.getAll(); \t} ' – gkc123

+0

Jako komentarz sugest spróbuj podjąć mniejsze kroki. Czy powracająca lista ciągów działa? – jstuartmilne

0

Muszę się dowiedzieć, dlaczego wiosna - boot nie rozpoznał kontrolera z oryginalną strukturą pakietu. Zrzuciłem wszystkie klasy Java do jednej paczki i ostatecznie uruchomiłem projekt demonstracyjny.

zmodyfikowanej struktury Java projektu:

Modified Java Project Structure

Klasa CircleController.java został również zmodyfikowany. Mam wszystkie rekordy usunięte z tabeli kręgu bez wymieniania konkretnej metody żądania, method=RequestMethod.GET.

package com.nomad.dubbed.app; 

import java.util.List; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RestController; 

@RestController 
public class CircleController { 
    @Autowired 
    private CircleService circleService; 

    @RequestMapping(value="/circles", method=RequestMethod.GET) 
    public List<Circle> getAll() { 
     return circleService.getAll(); 
    } 

} 
0

że ten sam problem i dodano @ComponentScan (basePackages = "package.name") do klasy aplikacji. Potem mój kontroler odpoczynku został rozpoznany.

pakiet com.nomad.dubbed.app;

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 

@SpringBootApplication 
@ComponentScan(basePackages = "com.spring.basepkg") 
public class Application { 

    public static void main(String[] args){ 
     SpringApplication.run(Application.class, args); 
    } 

}