问题描述
今天在项目中使用JSP包含指令(动态包含)引入一个html页面,打开浏览器测试时,却发现运行到加载的那里直接崩了。
如图:
目录结构及异常。
异常详情
08-Apr-2020 21:36:12.201 SEVERE [http-nio-8081-exec-3] org.apache.catalina.core.ApplicationDispatcher.invoke Servlet.service() for servlet [default] threw exception
java.io.FileNotFoundException: The requested resource [/ee/ee/html/TopPage.html] is not available
at org.apache.catalina.servlets.DefaultServlet.serveResource(DefaultServlet.java:852)
at org.apache.catalina.servlets.DefaultServlet.doGet(DefaultServlet.java:504)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
at org.apache.catalina.servlets.DefaultServlet.service(DefaultServlet.java:484)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:728)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:591)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:527)
at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:868)
at org.apache.jsp.index_jsp._jspService(index_jsp.java:138)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:476)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:528)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:810)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
08-Apr-2020 21:36:12.202 SEVERE [http-nio-8081-exec-3] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [jsp] in context with path [/ee] threw exception
java.io.IOException: An exception occurred processing [/index.jsp] at line [25]
22: <body>
23: <div class="container">
24: <p>${pageContext.request.contextPath}/html/TopPage.html</p>
25: <jsp:include page="${pageContext.request.contextPath}/html/TopPage.html" flush="true"/>
26:
27: <%-- <p id="error_msg" class="display-5" style="color: red;">${sessionScope.session_msg}</p>--%>
28:
Stacktrace:
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:504)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:528)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:810)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.FileNotFoundException: The requested resource [/ee/ee/html/TopPage.html] is not available
at org.apache.catalina.servlets.DefaultServlet.serveResource(DefaultServlet.java:852)
at org.apache.catalina.servlets.DefaultServlet.doGet(DefaultServlet.java:504)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
at org.apache.catalina.servlets.DefaultServlet.service(DefaultServlet.java:484)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:728)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:591)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:527)
at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:868)
at org.apache.jsp.index_jsp._jspService(index_jsp.java:138)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:476)
... 25 more
问题分析
可以清楚的看到所报的异常为文件找不到的异常,所以肯定是路径写错了,而且它还已经把错误的路径打印出来了。可以看到,contextPath重复拼接了。
解决方案
删去我们手动获取的contextPath即可。
思考
既然我们的问题解决了,那么为啥呢?
原来,
-
在服务器端默认是相对contextPath(一般与项目名一致,但两者概念不同,也可以不同)来解析的。
-
在浏览器端默认是相对域名(服务器地址)解析的。
添加斜杠/的情况
- 在服务器端,URL前添加斜杠/代表从contentPath开始。
- 在浏览器端,URL前添加斜杠/代表从域名(服务器地址)开始。
当然不添加斜杠/就代表从当前文件目录开始。
注意:上文所说的 在服务器或在浏览器 都是指在 服务器或浏览器执行的操作。还有就是服务器端向浏览器发送的重定向与上文所说的不同,重定向是发送什么地址浏览器就转向什么地址,不存在相对路径问题。
总结
所以涉及到浏览器端获取资源的,最好加上contextPath。
如:
注意:通过${pageContext.request.contextPath}
或request.getContextPath()
获取的contextPath,其前面都默认添加了斜杠/,不要再重复添加斜杠/,不然会直接覆盖掉域名(服务器地址)。
如图:
补充
我转载的大佬的文章:https://blog.csdn.net/weixin_43670802/article/details/104705147