


专栏:JavaEE 进阶跃迁营
个人主页:手握风云
目录
[1.1. 返回静态页面](#1.1. 返回静态页面)
[1.2. 返回数据 @ResponseBody](#1.2. 返回数据 @ResponseBody)
[1.3. 返回 HTML 代码片段](#1.3. 返回 HTML 代码片段)
[1.4. 返回 JSON](#1.4. 返回 JSON)
[1.5. 设置状态码](#1.5. 设置状态码)
一、响应
1.1. 返回静态页面

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<h1>我是 index 页面</h1>
</body>
</html>
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello</title>
</head>
<body>
<form action="/hello/v3" method="post">
<input type="submit" value="发送请求">
</form>
</body>
</html>
java
package com.yang.test1_15_2;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/return")
@RestController
public class ReturnController {
@RequestMapping("/returnPage")
public String returnPage() {
return "index.html";
}
}

按照上述代码,我们启动程序,在浏览器的地址栏输入http://127.0.0.1:8080/return/returnPage,会发现并没有按照预期返回 index.html 这个页面。http 响应把 "index.html" 只是当做了一个字符串。要想让 Spring MVC 正确识别出 index.html 是一个静态页面,我们就需要把 @RestController 改成 @Controller。

可是我们再次运行程序时,这个界面就会出现"404"错误。如果我们在 "index.html" 前面加上 "/" 就能正常显示。这个 "/" 就表示相对路径是 ""

如果 "index.html" 前面没有 "/",就默认的请求路径是 "return/index.html";如果 "index.html" 前面有 "/",就默认的请求路径是 "/index.html",我们还可以把浏览器请求路径的"/return/returnPage"省略掉,直接写"http://127.0.0.1:8080/"。


@RestController 与 @Controller 的关联与区别:从关联来看,@RestController 和 @Controller 均是 Spring 框架中用于标识 "控制器" 的核心注解,Spring 程序启动时会自动扫描并加载被这两个注解修饰的类,将其纳入 Spring 容器管理,核心作用都是接收前端发送的 HTTP 请求,并协调后续业务逻辑处理与响应操作,是 Spring MVC 中连接前端请求与后端服务的关键入口。且二者存在明确的底层语法关联,@RestController 本质是 @Controller 与 @ResponseBody 两个注解的 "组合注解",其源码中明确包含 @Controller 和 @ResponseBody 注解,意味着 @RestController 天然继承了 @Controller 作为控制器的核心能力,同时自带 @ResponseBody 的数据响应特性。
@RequestController 源码:
java
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Controller;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
@AliasFor(
annotation = Controller.class
)
String value() default "";
}
从区别来看,二者最核心的差异体现在 "响应内容类型" 与 "适用场景" 上。首先是响应内容类型不同:@Controller 作为传统控制器注解,默认行为是 "返回视图"(如 HTML 静态页面),即方法返回的字符串会被 Spring 解析为视图路径(如返回 "/index.html" 会跳转到 static 目录下的 index.html 页面);若需让 @Controller 修饰的方法返回数据(如文本、JSON),则必须在方法或类上额外添加 @ResponseBody 注解,否则会因 Spring 无法找到对应视图路径而报 404 错误。而 @RestController 因内置 @ResponseBody 注解,所有方法默认返回 "数据" 而非视图,方法返回的字符串、对象(如 HashMap、实体类)会被自动处理为 HTTP 响应正文(如文本格式、JSON 格式),不会被解析为视图路径,例如返回 "/index.html" 时,前端会直接显示该字符串而非跳转页面。
其次是适用场景不同:@Controller 更适合传统 "前后端不分离" 的项目,这类项目需要后端直接返回页面(如 JSP、HTML),例如传统管理系统中点击菜单后后端返回对应的页面视图;而 @RestController 则专为 "前后端分离" 项目设计,这类项目中前端负责页面渲染,后端仅需提供数据接口(如用户信息查询、业务数据提交),例如返回 JSON 格式的用户列表、计算结果等,无需处理视图相关逻辑。此外,@Controller 支持 "部分方法返回视图、部分方法返回数据" 的混合场景(只需在返回数据的方法上单独加 @ResponseBody),而 @RestController 无法实现返回视图的需求,因其类级别的 @ResponseBody 会强制所有方法返回数据,无法切换为视图响应模式。
1.2. 返回数据 @ResponseBody
@ResponseBody 是 Spring MVC 中用于指定方法或类返回 "数据" 而非 "视图" 的注解,即它会将方法的返回值直接作为 HTTP 响应正文(响应体)返回给前端,而非按照视图路径去查找页面文件(如 HTML)。
@ResponseBody 兼具类注解 和方法注解的属性,作用范围不同,效果也不同。如果作用在类上,该类中所有方法的返回值都会被视为 "数据",无需在每个方法上单独添加该注解;如果作用在方法上,仅当前方法的返回值被视为 "数据",类中其他未加该注解的方法仍默认返回视图。
java
package com.yang.test1_19_1;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@RequestMapping("/return")
@ResponseBody
@Controller
// 等价于 @RestController
public class ReturnController {
@RequestMapping("/returnPage")
public String returnPage() {
return "/index.html";
}
}

java
package com.yang.test1_19_1;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@RequestMapping("/return")
@Controller
public class ReturnController {
@RequestMapping("/returnPage")
public String returnPage() {
return "/index.html";
}
@RequestMapping("/returnData")
@ResponseBody
public String returnData() {
return "该方法返回数据";
}
}
如果我们去掉 returnData() 方法上的 @ResponseBody 注解,就会因为找不到 "该方法返回数据.html" 而报 404 错误。
1.3. 返回 HTML 代码片段
需在方法上添加 @ResponseBody 注解,确保返回的字符串被视为 "数据" 而非 "视图路径"。
java
package com.yang.test1_19_2;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@RequestMapping("/return")
@Controller
public class ReturnController {
@RequestMapping("/returnHTML")
@ResponseBody
public String returnHTML() {
return "<h1>我是一级标题</h1>";
}
}

我们接下来通过 Fiddler 抓包观察下响应结果,Content-Type 类型为 text/html,text/html 是 HTTP 协议中用于标识 "响应体为 HTML 格式" 的标准类型,这是浏览器能够解析 HTML 代码的核心原因。

| Content-Type 类型 | 含义 | 适用场景 |
|---|---|---|
text/html |
响应体为 HTML 格式 | 返回 HTML 代码片段、静态 HTML 页面 |
text/css |
响应体为 CSS 格式 | 返回 CSS 样式文件 |
application/javascript |
响应体为 JavaScript 格式 | 返回 JS 脚本文件 |
application/json |
响应体为 JSON 格式 | 返回 JSON 数据(如接口响应) |
1.4. 返回 JSON
Spring MVC 支持将后端方法的返回对象(如集合、自定义实体类、Map 等)自动转换为 JSON 格式数据,无需手动处理字符串拼接,底层依赖 jackson/databind 工具包(Spring MVC 已默认集成,无需额外引入),最终以 applicaion/json 格式的响应体返回给前端。通过 @ResponseBody 注解声明 "返回数据而非视图",Spring MVC 会自动完成 "对象 → JSON 字符串" 的转换。
java
package com.yang.test1_19_3;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@RequestMapping("/return")
@Controller
public class ReturnController {
@RequestMapping("/returnJSON")
public Person returnJSON() {
Person person = new Person();
person.setAge(22);
person.setName("Sandman");
person.setPassword("12345");
return person;
}
}
java
package com.yang.test1_19_3;
public class Person {
private int age;
private String name;
private String password;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}


1.5. 设置状态码
Spring MVC 会根据方法的返回结果自动设置 HTTP 响应状态码 (如成功返回数据时默认 200、资源未找到时默认 404 等),同时也支持开发者通过 **Spring MVC 内置对象 HttpServletResponse**手动指定响应状态码,以满足业务中对特定状态码的需求(如未授权返回 401、服务器错误返回 500 等)。
java
package com.yang.test1_19_4;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@RequestMapping("/return")
@Controller
public class ReturnController {
@ResponseBody
@RequestMapping("/setStatus")
public String setStatus(HttpServletResponse response) {
response.setStatus(502);
return "设置状态码成功";
}
}


如果说请求失败,并不会影响页面的显示。比如 B站的错误页面。
