Eclipse中Tomcat运行Java Servlet时index.jsp无法执行并出现StackOverflowError问题求助
嘿,看了你的代码和报错信息,我马上就发现问题出在哪了——无限递归的页面包含导致了StackOverflowError!
问题到底出在哪?
你直接运行index.jsp的时候,根本没走layoutServlet对吧?这就导致request里根本没有view这个属性,那<jsp:include page="${view}" />里的${view}就是空值。而JSP的<jsp:include>在page属性为空的时候,默认会包含当前页面!这就变成了index.jsp一直包含自己,循环往复直到把栈内存撑爆,直接抛出StackOverflowError。
至于你说新建相同项目能正常运行?大概率是你在新项目里是通过访问/start这个Servlet地址启动的,不是直接点index.jsp运行。这种情况下Servlet会提前把view设成subindex.jsp,页面包含的是正确的文件,自然不会出问题。
给你几个解决办法,按需选就行
1. 强制所有人走Servlet入口(推荐)
直接在web.xml里把欢迎页改成你的Servlet,这样不管是访问项目根路径还是直接打开项目,都会先经过layoutServlet:
<welcome-file-list> <welcome-file>/start</welcome-file> </welcome-file-list>
这样就彻底避免了有人直接访问index.jsp的情况,从根源上解决问题。
2. 给index.jsp加个兜底逻辑
如果必须允许直接访问index.jsp,那就在JSP里给view加个默认值,空的时候就用默认的页面:
<%-- views --%> <jsp:include page="${empty view ? '/views/subindex.jsp' : view}" />
这样就算没经过Servlet,也不会出现无限循环包含的情况。
3. 优化Servlet里的路径判断(可选)
你Servlet里用uri.contains("/ASM/start")判断有点死板,万一以后项目上下文路径改了(比如把ASM改成别的),这个判断就失效了。改成用Servlet路径判断更靠谱:
String path = request.getServletPath(); if("/start".equals(path)) { request.setAttribute("view","/views/subindex.jsp"); } else { request.setAttribute("view","/views/404.jsp"); }
最后验证一下
改完之后重启Tomcat,要么访问项目根路径,要么直接输/start地址,看看页面是不是正常加载了,控制台也不会再报栈溢出的错啦!
内容的提问来源于stack exchange,提问作者thanhyou00

