SpringMVC中如何为同一类提供不同JSON输出(视图层实现)
纯视图层实现SpringMVC多格式JSON输出(无额外Java代码)
作为SpringMVC新手,你想要完全在视图层控制JSON输出格式、不修改实体类/控制器代码,同时替代停止维护的json-taglib,下面给你几个实用且维护性好的方案:
方案1:Thymeleaf直接生成JSON(推荐,Spring官方生态)
Thymeleaf支持TEXT模板模式,可以直接输出纯JSON结构,完全在模板里控制哪些字段输出、如何处理嵌套属性,无需新增Java代码。
示例1:仅输出name的模板(person-simple.json)
放在src/main/resources/templates目录下:
[# th:remove="tag"] { "name": "[[${person.name}]]" } [/]
th:remove="tag":移除外层标签,确保输出纯JSON文本[[${person.name}]]:Thymeleaf变量替换,自动转义JSON特殊字符(如双引号、换行)
示例2:输出name+code+自定义处理Address的模板(person-full.json)
假设Address类有street和zipCode字段,这里只输出大写的street:
[# th:remove="tag"] { "name": "[[${person.name}]]", "code": "[[${person.code}]]", "address": { "street": "[[${#strings.toUpperCase(person.address.street)}]]" } } [/]
控制器配置(无需修改实体类)
控制器只负责把数据丢给模型,返回对应模板即可:
@Controller public class PersonController { @GetMapping("/person/simple") public String getSimplePerson(Model model) { // 初始化Person及Address数据 Person person = new Person(); person.setName("foo"); person.setCode(123L); Address address = new Address(); address.setStreet("Main St"); address.setZipCode("10001"); person.setAddress(address); model.addAttribute("person", person); return "person-simple"; // 返回简单JSON模板 } @GetMapping("/person/full") public String getFullPerson(Model model) { // 复用相同的数据初始化逻辑 Person person = new Person(); person.setName("foo"); person.setCode(123L); Address address = new Address(); address.setStreet("Main St"); address.setZipCode("10001"); person.setAddress(address); model.addAttribute("person", person); return "person-full"; // 返回完整JSON模板 } }
方案2:JSP原生生成JSON(传统项目适配)
如果你的项目已经在用JSP,也可以直接写JSON结构,配合JSTL处理变量:
简单JSON的JSP(person-simple.jsp)
<%@ page contentType="application/json;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> { "name": "<c:out value="${person.name}" escapeXml="true"/>" }
contentType="application/json":告诉浏览器返回的是JSON格式c:out escapeXml="true":自动转义JSON特殊字符,避免格式错误
完整JSON的JSP(person-full.jsp)
<%@ page contentType="application/json;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> { "name": "<c:out value="${person.name}" escapeXml="true"/>", "code": "<c:out value="${person.code}" escapeXml="true"/>", "address": { "street": "<c:out value="${fn:toUpperCase(person.address.street)}" escapeXml="true"/>" } }
替代json-taglib的靠谱方案
json-taglib确实已停止维护,目前最适合的替代方案就是上面的:
- Thymeleaf JSON模板:Spring官方推荐,活跃维护,生态完善,支持复杂的变量处理和逻辑控制
- JSP+JSTL原生写法:无需额外依赖,适合传统JSP项目
为什么选择视图层控制?
你拒绝在实体/控制器加注解的思路非常正确:
- 把JSON格式逻辑放在模板里,修改格式无需改Java代码、重新打包部署
- 支持热更新模板(配置模板热加载后,生产环境也能快速调整输出格式)
- 格式逻辑和业务逻辑完全解耦,代码更干净
内容的提问来源于stack exchange,提问作者vahidreza
相关产品推荐
相关产品推荐

