1. 概述
在实际开发中,虽然我们大多数时候用模板引擎(如 Thymeleaf、Freemarker)或前后端分离返回 JSON,但偶尔也会遇到需要直接从 Controller 返回纯 HTML 字符串的场景——比如写个简单的静态页面、做接口调试页,或者实现某个轻量级的嵌入式页面。
本文就来简单粗暴地讲清楚:如何让 Spring MVC 的 Controller 直接输出 HTML 内容,并避开几个常见的“踩坑”点。
2. Maven 依赖
要使用 Spring MVC 功能,首先确保引入了 spring-boot-starter-web
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.1.5</version>
</dependency>
✅ 这个 starter 已经包含了 Spring MVC 核心组件,比如 DispatcherServlet
、注解支持、消息转换器等,开箱即用。
⚠️ 注意:不需要额外引入视图层依赖(如 Thymeleaf),因为我们这次不走视图解析流程。
3. Controller 实现
核心关键在于:告诉 Spring 这个方法返回的是响应体内容,而不是逻辑视图名。
来看具体实现:
@Controller
public class HtmlController {
@GetMapping(value = "/welcome", produces = MediaType.TEXT_HTML_VALUE)
@ResponseBody
public String welcomeAsHTML() {
return "<html>\n" +
"<header><title>Welcome</title></header>\n" +
"<body>\n" +
"Hello world\n" +
"</body>\n" +
"</html>";
}
}
关键点解析:
- ✅
@Controller
:标识这是一个 Spring MVC 控制器,交由DispatcherServlet
调度处理。 - ✅
@GetMapping("/welcome")
:映射 GET 请求到/welcome
接口。 - ✅
produces = MediaType.TEXT_HTML_VALUE
:明确指定响应的Content-Type
为text/html
,防止浏览器误解析。 - ✅
@ResponseBody
:这是重中之重。它告诉 Spring:“别把这个字符串当成视图名称去查找模板,直接把它作为 HTTP 响应体返回。”
❌ 如果没有 @ResponseBody
,Spring 会尝试寻找名为 "Hello world..."
的视图(显然不存在),最终导致 404。
测试验证
启动应用后,使用 curl 测试:
curl -v http://localhost:8081/welcome
输出如下:
> GET /welcome HTTP/1.1
> Host: localhost:8081
>
< HTTP/1.1 200
< Content-Type: text/html;charset=UTF-8
< Content-Length: 123
<
<html>
<header><title>Welcome</title></header>
<body>
Hello world
</body>
</html>
可以看到:
- ✅ 状态码为 200
- ✅
Content-Type
正确设置为text/html;charset=UTF-8
- ✅ 响应体就是我们拼接的 HTML 字符串
4. 总结
通过本文你应该掌握了一个实用技巧:
用 @ResponseBody
+ produces = TEXT_HTML_VALUE
组合,即可让 Spring MVC Controller 直接返回纯 HTML 内容。
适用场景包括:
- 快速搭建内部工具页
- 返回简单的静态提示页
- 集成测试中的桩接口(stub endpoint)
- 不想引入模板引擎时的轻量方案
⚠️ 注意:生产环境大规模拼接 HTML 字符串容易出 XSS 或格式错误,建议仅用于简单场景。复杂页面仍推荐使用模板引擎或前后端分离架构。
完整示例代码已托管至 GitHub:
👉 https://github.com/spring-tutorials/html-response-demo