上期我们讲请求的时候,每个方法返回的数据就是响应,我们也可以返回一个静态页面,设置响应的状态码,Header信息等。
1. 返回静态页面
我们先在项目的static文件夹下创建一个HTML文件作为我们返回的页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>response1</h1>
</body>
</html>
写一个方法返回该html:
@RequestMapping("/Response")
@RestController
public class ResponseController {
@RequestMapping("/response1")
public String response1() {
return "/response1.html";
}
}
我们用浏览器访问这个接口:
和我们的预期不同,并没有返回页面,而是把 /response1.html 当作数据返回了。
这里我们需要说到@RestController 这个注解:
我选中@RestController 按下 ctrl+B跳转到注解的源码位置:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
这三个注解称为元注解,用来注解其他注解的注解:
- @Target 注解用于指定被修饰的注解可以应用的范围,它包含一个 ElementType 类型的数组参数。常见的 ElementType 包括 TYPE(类、接口、枚举)、FIELD(字段)、METHOD(方法)等。通过在自定义注解上使用 @Target 注解,可以限定该注解可以修饰的程序元素类型。例如这里表示只能用来注解类
- @Retention 注解用于指定被修饰的注解的生命周期,它包含一个 RetentionPolicy 类型的参数,常见的值包括 SOURCE(源码级别保留,编译时丢弃)、CLASS(编译时保留,运行时丢弃)、RUNTIME(运行时保留)。通过在自定义注解上使用 @Retention 注解,可以控制该注解的保留策略。
- @Documented 注解标记另一个注解,表示该注解应该包含在 Javadoc 中。如果一个自定义注解使用了 @Documented 注解修饰,那么当使用该注解修饰其他程序元素时,这些元素会在生成的文档中包含该注解的信息。
@Controller
- @Controller 表示被 @RestController 注解修饰的类是一个控制器。前面我们讲Spring MVC 入门的时候提到过:
@ResponseBody
- @ResponseBody 表示该控制器的方法返回的结果将直接作为响应体发送给客户端,而不进行页面跳转或模板渲染,这里相当于被 @RestController 注解修饰的类的所有方法都被加上了@ResponseBody注解,也就解释了为什么没有返回页面。
综上所述:@RestController注解就相当于 @Controller @ResponseBody这两个注解
所以我们可以把@RestController注解 改为 @Controller 注解,就能返回一个静态页面了:
@RequestMapping("/Response")
@Controller
public class ResponseController {
@RequestMapping("/response1")
public String response1() {
return "/response1.html";
}
}
注意 返回页面时以static为当前页面,斜杠(/)不可省略
由于现在流行前后端分离模式,后端项目是没有视图的,也就不负责返回视图,后端只返回数据即可,所以才有了@RestController
如果在@Controller 注解修饰下的类要返回数据需要给对应方法加上@ResponseBody
在@RestController注解中,"REST" 的含义是 Representational State Transfer,即"表述性状态转移"。REST 是一种软件架构风格,它是一种设计和开发网络应用程序的方式,旨在促进系统之间的互操作性和可伸缩性。
2. 返回HTML代码片段
返回HTML代码片段,我们直接按照返回数据的方式返回HTML代码即可
@RequestMapping("/Response")
@Controller
public class ResponseController {
@ResponseBody
@RequestMapping("/response2")
public String response2() {
return "<h1>这是一个HTML代码片段<h1>";
}
}
Spring会根据返回的结果自动设置Content-Type
3. 返回JSON
返回一个对象时默认情况下 Spring MVC 会将这个对象转换为 JSON 格式,并设置响应头的 Content-Type 为 application/json。
@ResponseBody
@RequestMapping("/response3")
public Map<String, String> response3() {
Map<String, String> map = new HashMap<>();
map.put("k1", "v1");
map.put("k2", "v2");
map.put("k3", "v3");
map.put("k4", "v4");
return map;
}
4. 设置状态码
Spring 会根据我们的方法的返回结果自动设置响应状态码,我们也可以手动指定状态码:
@ResponseBody
@RequestMapping("/response4")
public String response4(HttpServletResponse response) {
response.setStatus(418);
return "设置状态码成功";
}
HttpServletResponse 和HttpServletRequest对应,代表响应,包含响应中的全部内容。
可以看到状态码被设置成了418
5. 设置Header
Http的响应报头也可以传递一些信息,如Content-Type,Local等,这些信息通过@RequestMapping 注解的属性来实现,我们先看看@requestMapping 的源码:
- @Target({ElementType.TYPE, ElementType.METHOD}):指定了该注解可以应用在类和方法上。
- @Retention(RetentionPolicy.RUNTIME):指定了该注解会在运行时保留,因此可以通过反射机制来访问注解信息。
- @Documented:表示该注解应该被包含在 Java 文档中。
- @Mapping:这是一个元注解,表示该注解是一个映射注解,用于将请求映射到处理器方法。
- @Reflective({ControllerMappingReflectiveProcessor.class}):指定了该注解在处理时会使用 ControllerMappingReflectiveProcessor 进行反射处理。
- String name() default "":用于指定映射的名称。
- @AliasFor("path") String[] value() default {}:用于指定映射的路径,同时通过 @AliasFor 注解将 value() 方法和 path() 方法关联起来,表示它们具有相同的含义。
- RequestMethod[] method() default {}:用于指定请求的 HTTP 方法类型,如:GET/POST
- String[] params() default {}:用于指定请求需要满足的参数条件。
- String[] headers() default {}:用于指定请求需要满足的请求头条件。
- String[] consumes() default {}:用于指定处理请求的请求体(Content-Type)类型。
- String[] produces() default {}:用于指定处理请求的响应体(Accept)类型。
示例:指定请求方法的类型
@ResponseBody
@RequestMapping(value = "/response5" , method = RequestMethod.GET)
public String setMethod() {
return "接收请求成功";
}
指定只能接收GET请求:
设置响应返回的类型 :
@ResponseBody
@RequestMapping("/response6")
public String setContentType() {
return "\"Key\", 200";
}
不进行设置时 Content-Type时text/plain
@ResponseBody
@RequestMapping(value = "/response6", produces = "application/json")
public String setContentType() {
return "\"Key\", 200";
}
设置为JSON: