【异常】记一次因注解@RestController没加(@RestController不会用),导致无法调用Controller层的方法

一、背景

我想要调用一个Controller,定义的内容如下

@RequestMapping("/demo")
public class demoController {
    @GetMapping("/doSomething")
    public JSONObject doSomething() {
        JSONObject json = new JSONObject();
        json.set("title", "我是doSomething 的 title");
        json.set("content", "我是doSomething 的 content");
        return json;
    }
}

但是我得到了如下的结果
【异常】记一次因注解@RestController没加(@RestController不会用),导致无法调用Controller层的方法_第1张图片
其中工程是基于SpringCloudAlibaba微服务搭建的,而问题代码是写在xxx-admin模块中,其中的路由/xxx为SpringCloud Gateway映射的网关路由,如下

#网关路由服务配置
spring:
  cloud:
    # 网关配置
    gateway:
      discovery:
        locator:
          lowerCaseServiceId: true
          enabled: true
      routes:
        # 管理业务
        - id: xxx-admin
          uri: lb://xxx-admin
          predicates:
            - Path=/xxx/**
          filters:
            - StripPrefix=1

那为什么会提示Not Found呢?不是路径都匹配了吗?哎,又被基础不扎实坑了一把!

二、问题解决

2.1 加一个@Controller注解

初步诊断,原因是没有定义到@Controller,Spring都不认识这个类,肯定不能找到啊
那就尝试加一个@Controller?于是编写了如下的代码

@Controller
@RequestMapping("/demo")
public class demoController {

    @GetMapping("/doSomething")
    public JSONObject doSomething() {
        JSONObject json = new JSONObject();
        json.set("title", "我是doSomething 的 title");
        json.set("content", "我是doSomething 的 content");
        return json;
    }
}

怎么还是提示未找到呢?奇怪~ 继续百度
【异常】记一次因注解@RestController没加(@RestController不会用),导致无法调用Controller层的方法_第2张图片

2.2 加一个@Controller注解 + @ResponseBody注解

发现大家都会加上@ResponseBody注解,那我也加上试试
(典型的不理解背后原理盲目加注解)

于是改出了如下代码

@Controller
@RequestMapping("/demo")
public class demoController {

    @GetMapping("/doSomething")
    @ResponseBody
    public JSONObject doSomething() {
        JSONObject json = new JSONObject();
        json.set("title", "我是doSomething 的 title");
        json.set("content", "我是doSomething 的 content");
        return json;
    }
}

发现现在可以正常返回了。
【异常】记一次因注解@RestController没加(@RestController不会用),导致无法调用Controller层的方法_第3张图片

2.3 加一个@RestController注解

那有没有更加优美的写法呢?答案肯定是有的!因为不涉及到页面跳转,因此可以直接@RestController,如果要求方法返回的是JSON格式数据,而不是跳转页面,可以直接在类上标注@RestController,而不用在每个方法中标注@ResponseBody,简化了开发过程。最终问题解决后的代码如下:

@RestController
@RequestMapping("/demo")
public class demoController {

    @GetMapping("/doSomething")
    public JSONObject doSomething() {
        JSONObject json = new JSONObject();
        json.set("title", "我是doSomething 的 title");
        json.set("content", "我是doSomething 的 content");
        return json;
    }
}

此时看到,也是可以正常返回响应结果了。
【异常】记一次因注解@RestController没加(@RestController不会用),导致无法调用Controller层的方法_第4张图片

三、@RestController注解回顾

Spring 4.0引入了@RestController,这是一个控制器的专用版本,它是一个方便的注释。
在Spring中 , @RestController注解,相当于@ResponseBody@Controller
所以想要理解@RestController注解就要先了解@Controller@ResponseBody注解。

3.1 @Controller注解

@Controller注解是Spring框架中的一种注解,它的作用是用于标识控制器类、控制器组件、控制层组件,使其成为处理请求的组件,可以处理HTTP请求和其他种类的请求。

@Controller注解用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller对象,即在一个类上添加@Controller注解,表明了这个类是一个控制器类。控制器组件可以处理并响应应用程序中的用户请求,并将请求映射到适当的处理程序。

3.2 @RequestMapping注解

@Controller注解的类注入Spring容器中,只是该类成为处理器的第一步,
想要修炼大成,还需要在该类中添加注解@RequestMapping

分发处理器会扫描使用了使用该注解的类的方法,并检测该方法是否使用了@RequestMapping注解
可以把Request请求Header部分的值绑定到方法的参数上。

@RequestMapping注解是用来映射请求的,即指明处理器可以处理哪些URL请求
@RequestMapping注解既可以用在类上,也可以用在方法上。
当使用@RequestMapping标记控制器类时,方法的请求地址是相对类的请求地址而言的;
当没有使用@RequestMapping标记类时,方法的请求地址是绝对路径。

@RequestMapping的地址
可以是uri变量,并且通过@PathVariable注解获取作为方法的参数。
也可以是通配符来筛选请求地址。

什么时候用@ResponseBody注解 ?
如果想要方法直接返回结果,而不是跳转页面,这就要用到@ResponseBody注解了。

三、@ResponseBody注解

通过使用@RestController批注对控制器类进行注释,您不再需要将@ResponseBody添加到所有请求映射方法中。@ResponseBody注释默认处于活动状态。

异步请求,@ResponseBody注解表示方法的返回值直接以指定的格式写入Http Response Body中,而不是解析为跳转路径。格式的转换是通过HttpMessageConverter中的方法实现的,因为它是一个接口,因此由其实现类完成转换。

@ResponseBody注解表用于将Controller中的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的Body数据区。

3.1 使用场景:

如果要求方法返回的是JSON格式数据,而不是跳转页面,可以直接在类上标注@RestController,而不用在每个方法中标注@ResponseBody,简化了开发过程。

即返回的数据内容,不是HTML标签的页面,而是其他某个格式的数据时(如JSON、XML等)使用。比如本文使用的就是返回JSON数据的场景。

你可能感兴趣的:(001,-,基础开发能力与编程语言,java,spring,spring,cloud,idea,spring,boot)