记一次ViewResolver引起的问题
文章目录
问题背景
公司的项目基于SpringBoot开发,基本上所有接口都是Restful风格的,接收json参数,返回json数据。一般控制类上直接用
@RestController
或者@Controller
+@ResponseBody
来将对象序列化后返回给前端。
项目中还有少数几个接口是通过redirect:xxx
的方式进行重定向的,其中包括微信登录授权。这些接口需要用到Spring的ViewResolver
实现类进行视图解析,得到viewName对应的View
对象,然后由View
对象进行视图的渲染(render)。
解决过程
-
早上10:30左右,测试人员反映微信公众号的登录页面加载错误,出现空白错误页面,页面显示
Whitelabel Error Page
;
-
查看服务器日志,显示
javax.servlet.ServletException: Could not resolve view with name 'redirect:https:
-
搜索该错误信息,查询到一堆博客等资料,都未能解决;
-
开始排查代码提交记录,发现
pom.xml
中删除了springcloud相关的5个依赖,添加依赖后,服务恢复正常。
查找原因
- 服务恢复后,开始查找springcloud导致该问题的原因,逐一排除springcloud的5个依赖,发现是
spring-cloud-starter-hystrix-dashboard
包中的spring-boot-stater-freemarker
jar包影响; - 原服务中有该依赖和freemarker的jar包,服务可以正常进行
redirect
,排除了spring-cloud-starter-hystrix-dashboard
后,freemarker的jar包不在classpath
中,服务异常,不能进行redirect
重定向; - 开车查找FreeMarker的jar包在服务中的作用,单步调试到
DispatcherServlet
的render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response)
方法,发现:如果通过viewName
无法解析到相应的View
对象,则会抛出javax.servlet.ServletException: Could not resolve view with name
异常,详见源码:
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
//省略
View view;
//如果使用 viewName 来关联一个View,则使用ViewResolve