Spring MVC 不支持单请求同时渲染 HTML 与 JSON,而是通过 ViewResolver 链优先级和 @ResponseBody 语义分离路径:返回视图名走 HTML 渲染,加 @ResponseBody 则跳过 ViewResolver 直接序列化为 JSON。

Spring MVC 本身不支持“同时渲染 HTML 与 JSON”——它按请求响应路径和返回值语义自动选择一种视图策略。真正可行的是:**在同一个项目中,根据控制器方法的返回方式,分别走 HTML 渲染链或 JSON 序列化链**。核心靠 ViewResolver 链的优先级 + @ResponseBody 的语义切换实现,而不是让单个请求既返回页面又返回 JSON。
ViewResolver 链必须有序,且仅第一个匹配成功的生效
DispatcherServlet 按 order 升序遍历所有 ViewResolver,调用 resolveViewName()。只要某个 resolver 能根据逻辑视图名(如 "user/list")找到对应 View 实例(如 JSP 文件存在、Thymeleaf 模板存在),就停止查找并使用它渲染;后续 resolver 完全不参与。因此:
- order 值越小,优先级越高(例如 order=1 比 order=2 更早被尝试)
- InternalResourceViewResolver(JSP)通常设为较高 order(如 2),避免拦截所有字符串返回
- ContentNegotiatingViewResolver 应设为最低 order(如 0),因为它不直接解析,而是委托给其他 resolver,需最先介入内容协商
- 若未配置 ContentNegotiatingViewResolver,@ResponseBody 方法会跳过整个 ViewResolver 链,直接走 HttpMessageConverter
@ResponseBody 是 JSON 路径的开关,与 ViewResolver 无关
当 Controller 方法标注 @ResponseBody,Spring MVC 就不再把返回值当作逻辑视图名,而是直接序列化为 HTTP 响应体。此时:
- 完全绕过所有 ViewResolver,不查任何模板文件
- 依赖已注册的 HttpMessageConverter(如 MappingJackson2HttpMessageConverter)将对象转成 JSON
- 响应头自动设为 application/json;无需手动 setContentType
- 即使该方法返回字符串 "success",也会原样输出为 JSON 字符串(加引号),除非返回 ResponseEntity 或自定义 Converter
典型配置组合:JSP + JSON 共存
以 Spring Boot 2.7+ 或传统 XML/JavaConfig 为例,关键点在于分离职责:
立即学习“Java免费学习笔记(深入)”;
- 保留 InternalResourceViewResolver 处理 JSP(prefix="/WEB-INF/views/", suffix=".jsp", order=2)
- 添加 MappingJackson2HttpMessageConverter(默认已注册,确保 jackson-databind 在 classpath)
- Controller 中:返回 String 视图名 → 走 JSP;返回对象 + @ResponseBody → 走 JSON
- 示例:
HTML 路径:@GetMapping("/users") public String list(Model model) { model.addAttribute("users", service.findAll()); return "user/list"; }
JSON 路径:@GetMapping("/api/users") @ResponseBody public List<user> apiList() { return service.findAll(); }</user>
进阶:用 ContentNegotiatingViewResolver 统一协商格式
若希望同一 URL(如 /users)根据 Accept 头返回 HTML 或 JSON(即浏览器访问返回页面,curl -H "Accept: application/json" 返回 JSON),需启用内容协商:
- 配置 ContentNegotiatingViewResolver(order=0),它本身不渲染,只根据请求头选 delegate resolver
- 注册多个 delegate:InternalResourceViewResolver(处理 text/html)、MappingJackson2JsonView(处理 application/json)
- 注意:MappingJackson2JsonView 是 View 实现,不是 MessageConverter;它属于 ViewResolver 链,适用于非 @ResponseBody 场景
- 实际更推荐保持路径分离(/users vs /api/users),语义清晰、调试简单、缓存友好



















