我想要调用一个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;
}
}
但是我得到了如下的结果
其中工程是基于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呢?不是路径都匹配了吗?哎,又被基础不扎实坑了一把!
初步诊断,原因是没有定义到@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;
}
}
发现大家都会加上@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
,如果要求方法返回的是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;
}
}
Spring 4.0引入了@RestController
,这是一个控制器的专用版本,它是一个方便的注释。
在Spring中 , @RestController
注解,相当于@ResponseBody
+ @Controller
所以想要理解@RestController
注解就要先了解@Controller
和@ResponseBody
注解。
@Controller
注解是Spring框架中的一种注解,它的作用是用于标识控制器类、控制器组件、控制层组件,使其成为处理请求的组件,可以处理HTTP请求和其他种类的请求。
@Controller
注解用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller对象,即在一个类上添加@Controller注解,表明了这个类是一个控制器类。控制器组件可以处理并响应应用程序中的用户请求,并将请求映射到适当的处理程序。
将
@Controller
注解的类注入Spring容器中,只是该类成为处理器的第一步,
想要修炼大成,还需要在该类中添加注解@RequestMapping
。
分发处理器会扫描使用了使用该注解的类的方法,并检测该方法是否使用了@RequestMapping
注解
可以把Request请求Header部分的值绑定到方法的参数上。
@RequestMapping
注解是用来映射请求的,即指明处理器可以处理哪些URL请求
@RequestMapping
注解既可以用在类上,也可以用在方法上。
当使用@RequestMapping
标记控制器类时,方法的请求地址是相对类的请求地址而言的;
当没有使用@RequestMapping
标记类时,方法的请求地址是绝对路径。
@RequestMapping
的地址
可以是uri变量,并且通过@PathVariable
注解获取作为方法的参数。
也可以是通配符来筛选请求地址。
什么时候用@ResponseBody
注解 ?
如果想要方法直接返回结果,而不是跳转页面,这就要用到@ResponseBody
注解了。
通过使用
@RestController
批注对控制器类进行注释,您不再需要将@ResponseBody
添加到所有请求映射方法中。@ResponseBody
注释默认处于活动状态。
异步请求,@ResponseBody
注解表示方法的返回值直接以指定的格式写入Http Response Body中,而不是解析为跳转路径。格式的转换是通过HttpMessageConverter中的方法实现的,因为它是一个接口,因此由其实现类完成转换。
@ResponseBody
注解表用于将Controller中的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的Body数据区。
如果要求方法返回的是JSON格式数据,而不是跳转页面,可以直接在类上标注@RestController
,而不用在每个方法中标注@ResponseBody
,简化了开发过程。
即返回的数据内容,不是HTML标签的页面,而是其他某个格式的数据时(如JSON、XML等)使用。比如本文使用的就是返回JSON数据的场景。