繁体   English   中英

没有类级别的请求映射,Spring Boot注册Rest控制器不起作用

[英]spring boot registering rest controller doesn't work without class level requestmapping

引导应用程序,但是,即使我的服务组件在Spring上下文中显示为已注册的bean,其URL也未得到注册。 基本上,要注册具有方法级别@RequestMapping批注的组件,我需要定义类级别的请求映射。 然后,它的spring上下文能够注册url处理程序。

我的目录结构看起来像;

├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── awesomecrypto
│   │   │           └── backend
│   │   │               ├── SpringBootApp.java
│   │   │               ├── entity
│   │   │               │   └── MarketData.java
│   │   │               ├── repository
│   │   │               │   └── MarketDataRepository.java
│   │   │               └── service
│   │   │                   └── MarketDataService.java
│   │   └── resources

SpringBootApp.java

package com.awesomecrypto.backend;

// import statements.

@SpringBootApplication
public class SpringBootApp {

    public static void main(String[] args) {
        ApplicationContext applicationContext = SpringApplication.run(SpringBootApp.class, args);

        for (String name: applicationContext.getBeanDefinitionNames()) {
            System.out.println(name);
        }
    }
}

MarketDataService

package com.awesomecrypto.backend.service;

// import statements here.

@Component
public class MarketDataService {

    @Autowired
    private MarketDataRepository marketDataRepository;

    @GetMapping("/marketData")
    @ResponseBody
    public String getMarketData() {
        return "foobar";
    }
}

没有在MarketDataService类级别上定义@RequestMapping ,就不会为“ / marketData” URL注册任何URL处理程序。

2018-05-28 15:15:11.357  INFO 30618 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2018-05-28 15:15:11.357  INFO 30618 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1295 ms
2018-05-28 15:15:11.460  INFO 30618 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Servlet dispatcherServlet mapped to [/]
2018-05-28 15:15:11.465  INFO 30618 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-05-28 15:15:11.465  INFO 30618 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-05-28 15:15:11.465  INFO 30618 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-05-28 15:15:11.465  INFO 30618 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2018-05-28 15:15:11.601  INFO 30618 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-05-28 15:15:11.813  INFO 30618 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6c65519: startup date [Mon May 28 15:15:10 PDT 2018]; root of context hierarchy
2018-05-28 15:15:11.915  INFO 30618 --- [           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.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-05-28 15:15:11.916  INFO 30618 --- [           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.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-05-28 15:15:11.939  INFO 30618 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-05-28 15:15:11.939  INFO 30618 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]

另一方面, marketDataService是在春季上下文中注册的,这没有任何意义。 这是相关的getBeanDefinitionNames日志。

org.springframework.context.event.internalEventListenerFactory
springBootApp
org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory
marketDataRepository
marketDataService
org.springframework.boot.autoconfigure.AutoConfigurationPackages
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
org.springframework.boot.autoconfigure.condition.BeanTypeRegistry

现在,如果我在MarketDataService顶部添加@RequestMapping("/test") ,那么spring将注册一个URL处理程序。

2018-05-28 15:20:31.320  INFO 31536 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/test/marketData],methods=[GET]}" onto public java.lang.String com.awesomecrypto.backend.service.MarketDataService.getMarketData()

我正在运行应用程序;

mvn清洁包装

mvn spring-boot:运行

网络上的所有示例都没有提到这一点,并且看起来它不是类级别的RequestMapping,但我做不到。 感谢您的帮助。 谢谢!

您的@GetMapping批注将被忽略,因为MarketDataService类的顶部没有@Controller类型的批注。

在您的情况下,您应该使用@RestController (本身带有@Controller@ResponseBody注释):

@RestController
public class MarketDataService {

    @Autowired
    private MarketDataRepository marketDataRepository;

    @GetMapping("/marketData")
    public String getMarketData() {
        return "foobar";
    }

}

在类上使用@RequestMapping是将给定参数以及给定路径参数传递给同一类中的子级映射。

例如,在类MarketDataService上方添加@RequestMapping("/api")意味着要触发getMarketData()方法的路径将是/api/marketData而不是/marketData

同样,如果您添加@RequestMapping(value = "/api", produces = "application/json") ,它将把produces = "application/json"参数传递给@GetMapping("/marketData")

当控制器用于对给定资源进行CRUD时,我经常在类上使用@RequestMapping ,例如:

@RestController
@RequestMapping("/marketData")
public class MarketDataService {

    @Autowired
    private MarketDataRepository marketDataRepository;

    @PostMapping("")
    public String createMarketData() {
        // ...
    }

    @GetMapping("")
    public String getAllMarketData() {
        // ...
    }

    @GetMapping("/{id}")
    public String getMarketDataById(@PathVariable Long id) {
        // ...
    }

    @DeleteMapping("")
    public String deleteAllMarketData() {
        // ...
    }

    @DeleteMapping("/{id}")
    public String deleteMarketDataById(@PathVariable Long id) {
        // ...
    }

    // ...

}

您在类级别不需要RequestMapping。 将您的代码更改为此,它将为您工作。

 @RestController
 public class MarketDataService {

    @Autowired
    private MarketDataRepository marketDataRepository;

    @GetMapping("/marketData")
    public String getMarketData() {
     return "foobar";
    }
  }

我鼓励您阅读有关Spring MVC架构的更多信息。

https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc

您也可以阅读用于RequestMapping的javaDocs,RestController。

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/RestController.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM