spring mvc自定义视图解析器的核心是接管“逻辑视图名→视图实例→http响应输出”链条,绕过默认模板引擎,通过继承abstractcachingviewresolver实现匹配与缓存,按前缀(如xml:、excel:)创建对应view实例,并在render中设置mime类型、编码及流式输出。

Spring MVC 自定义视图解析器渲染特定格式,核心是接管“逻辑视图名 → 视图实例 → HTTP 响应输出”这一链条,绕过默认模板引擎(如 JSP、Thymeleaf),直接控制响应内容的类型与写入方式。
明确你要渲染的格式类型
不同格式决定 View 的实现逻辑和响应头设置:
- 纯文本:设 Content-Type 为
text/plain;charset=UTF-8,用response.getWriter()输出字符串 - XML:设 Content-Type 为
application/xml或text/xml,可用 JAXB 或 StringBuilder 手动拼接或序列化对象 - Excel(.xlsx):设 Content-Type 为
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,用 Apache POI 写入response.getOutputStream() - SVG / PDF / 自定义 HTML 片段:按对应 MIME 类型设置,并在 render 中直接写入原始字节或字符流
实现 ViewResolver:匹配逻辑视图名并返回 View 实例
推荐继承 AbstractCachingViewResolver,它自带缓存且简化开发:
- 重写
loadView(String viewName, Locale locale)方法,根据命名规则识别目标格式(例如以excel:、xml:或svg:开头) - 匹配成功时 new 对应的 View 实例(如
new ExcelView()),否则返回null让后续解析器处理 - 调用
setOrder(10)确保优先级高于默认解析器(默认 order 是Integer.MAX_VALUE)
实现 View:完成实际响应输出
View 接口只需两个方法,但这是格式落地的关键:
-
getContentType():必须返回准确的 MIME 类型,比如"application/xml;charset=UTF-8"或"image/svg+xml" -
render(Map model, HttpServletRequest req, HttpServletResponse resp):- 先调用
resp.setContentType(getContentType())和resp.setCharacterEncoding("UTF-8") - 根据格式选择输出方式:
resp.getWriter()(文本类)、resp.getOutputStream()(二进制类,如 Excel、PDF) - 从 model 中提取数据,执行序列化、模板填充或流写入,**不调用 forward 或 include**
- 先调用
注册并启用你的解析器
确保 Spring 容器加载该 Bean,并被 DispatcherServlet 使用:
- Java 配置方式(推荐):
@Bean
public ViewResolver customViewResolver() {
CustomViewResolver resolver = new CustomViewResolver();
resolver.setOrder(10);
return resolver;
} - XML 配置方式:
- 控制器中返回匹配的逻辑视图名,例如:
return "xml:userProfile";或return "excel:report2024";











