Rest Controller无法识别Spring Boot App中的GET请求

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rest Controller无法识别Spring Boot App中的GET请求相关的知识,希望对你有一定的参考价值。

我正在尝试使用Spring Boot实现简单的演示MVC应用程序,但在执行应用程序时出现404错误。 uri是`http://localhost:8080/',它显示名为circle的表中的所有行。

  • Spring Boot:1.3.3.RELEASE
  • Java版本:1.8.0_65
  • 数据库:Apache Derby 10.12.1.1

Maven Java项目:

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


circle controller.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();
    


circle repository.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> 


circle service.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.hml

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

数据库已启动并运行,表圈中有5行:

enter image description here

默认的uri(/ beans,/ health ..)工作正常,但无法识别已实现的控制器。在控制台中没有显示这样的错误,下面是我发送请求后在控制台中打印的日志转储。

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=[org.springframework.web.servlet.resource.PathResourceResolver@6c13019c]]] 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.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView@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.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView@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

答案

为您的控制器使用不同的URL。 spring-boot中的“​​/”映射到位于META-INF / resources和src / main / resources / static /中的静态资源。

编辑:忘记上面并在您的应用程序类中执行以下操作:

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


弹簧靴组件扫描不会发现您的休息控制器。根据这个文档http://docs.spring.io/spring-boot/docs/current/reference/html/ ... spring扫描包含@SpringBootApplication注释的类所在的包下面的包。您的控制器位于并行包中。

另一答案

我必须研究更多为什么spring-boot无法识别原始包结构的控制器。我将所有java类转储到一个包中,最后运行了演示项目。

修改后的Java项目结构:

Modified Java Project Structure

CircleController.java类也被修改了。我从圆圈表中删除了所有记录,但没有提到具体的请求方法,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();
    


另一答案

我有同样的问题,我在Application类中添加了@ComponentScan(basePackages =“package.name”)。之后,我的休息控制器被识别出来。

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


另一答案

你能尝试添加@ResponseBody Annotation吗?

@RequestMapping(method=RequestMethod.GET)
@ResponseBody
    public List<Circle> getAll() 
        return circleService.getAll();
    
另一答案

在我看来,这个可见性问题出现在我们将组件扫描留给Spring时,它有一种使用标准约定查找类的特定方法。在这种情况下,Starter类(Application)位于com.nomad.dubbed.app包中,将Controller放在下面一级将帮助Spring使用默认的组件扫描机制查找类。将CircleController放在com.nomad.dubbed.app.controller下可以解决问题。

另一答案

我有一个类似的问题。在Application类上添加注释@SpringBootApplication(scanBasePackages = “com.nomad.dubbed”)对我有用。

另一答案

这背后发生了什么。

@SpringBootApplication注释是@Configuration @EnableAutoConfiguration @ComponentScan的组合。

没有参数的@ComponentScan告诉框架在同一个包及其子包中查找组件/ bean。

你用Application注释的@SpringBootApplication类在com.nomad.dubbed.app包中。因此它会扫描该包及其下的子包(如com.nomad.dubbed.app.*)。但你的CircleController是在com.nomad.dubbed.controller包内,默认情况下不扫描。您的存储库也不属于默认扫描包,因此Spring框架也不会发现它们。

那么现在该做什么?,你有两种选择。

选项1

Application类移动到顶级目录(包)。在你的情况下com.nomad.dubbed包。然后,由于所有控制器和其他存储库都在子包中,因此框架将发现它们。

选项2

使用@ComponentScan注释和basePackages参数,以及@SpringBootApplication类中的Application,如下所示。

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

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

以上是关于Rest Controller无法识别Spring Boot App中的GET请求的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security 无法识别自己的加密

Spring Rest Controller PUT 方法请求正文验证?

Spring Boot 忽略 Rest Controller 中的 Jackson 注释

Spring Boot Rest Controller 通用 POST 类型

Spring Boot Rest Controller:返回默认错误 JSON

Angular 2 + CORS + 带有 Spring Security 的 Spring Boot Rest Controller