自己配置的tomcat 部署应用时提示错误信息:org.apache.catalina.core.ApplicationContext.log ssi: Can't find file: /index.html
ERROR ErrorPageFilter Cannot forward to error page for request [/] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false
现象如下图所示:
这个报错的结果就是:浏览器访问项目时 提示404。修改配置过的tomcat版本为8.5.51
奇怪的是:没有配置过的tomcat是可以正常部署应用的,
这个应用是一个spring boot项目, 这个项目里的index.html 是位于项目下的WEB-INF\classes\static下的; 这个 index.html的页面指定方式是:默认读取静态文件夹的根目录static下的文件。
初步判断是由于:配置的tomcat的某个配置影响了这个静态页面资源的加载。
我们再来看 报错信息里的 :org.apache.catalina.core.ApplicationContext.log ssi: Can't find file: /index.html
ssi是什么?
SSI是Server Side Includes的缩写,是嵌入到HTML页面的一组指令的集合。在返回请求的页面(包含SSI指令)前,服务器会处理这些指令,并用处理的结果替换指令,然 后把页面返回。这样就允许在HTML页面中添加动态产生的内容。
tomcat 对于ssi的设置 有两种方式 :在tomcat安装目录的 conf/目录下找到web.xml文件
1、SSI Servlet,即web.xml里 SSI servlet和servlet-mapping
2、SSI filter,即web.xml里SSI filter和filter-mapping
在当前问题里,web.xml的对于ssi的配置用的是:
<!-- NOTE: An SSI Filter is also available as an alternative SSI -->
<!-- implementation. Use either the Servlet or the Filter but NOT both. -->
<!-- -->
<!-- Server Side Includes processing servlet, which processes SSI -->
<!-- directives in HTML pages consistent with similar support in web -->
<!-- servers like Apache. Traditionally, this servlet is mapped to the -->
<!-- URL pattern "*.shtml". This servlet supports the following -->
<!-- initialization parameters (default values are in square brackets): -->
<!-- -->
<!-- buffered Should output from this servlet be buffered? -->
<!-- (0=false, 1=true) [0] -->
<!-- -->
<!-- debug Debugging detail level for messages logged -->
<!-- by this servlet. [0] -->
<!-- -->
<!-- expires The number of seconds before a page with SSI -->
<!-- directives will expire. [No default] -->
<!-- -->
<!-- isVirtualWebappRelative -->
<!-- Should "virtual" paths be interpreted as -->
<!-- relative to the context root, instead of -->
<!-- the server root? [false] -->
<!-- -->
<!-- inputEncoding The encoding to assume for SSI resources if -->
<!-- one is not available from the resource. -->
<!-- [Platform default] -->
<!-- -->
<!-- outputEncoding The encoding to use for the page that results -->
<!-- from the SSI processing. [UTF-8] -->
<!-- -->
<!-- allowExec Is use of the exec command enabled? [false] -->
<servlet>
<servlet-name>ssi</servlet-name>
<servlet-class>
org.apache.catalina.ssi.SSIServlet
</servlet-class>
<init-param>
<param-name>buffered</param-name>
<param-value>1</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>expires</param-name>
<param-value>666</param-value>
</init-param>
<init-param>
<param-name>isVirtualWebappRelative</param-name>
<param-value>false</param-value>
<!--<param-value>true</param-value> -->
</init-param>
<init-param>
<param-name>inputEncoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>outputEncoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<load-on-startup>4</load-on-startup>
</servlet>
<!-- The mapping for the SSI servlet -->
<servlet-mapping>
<servlet-name>ssi</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
根据与正常部署应用的tomcat的web.xml配置文件比对,可以发现:
正常的web.xml配置(tomcat 8.0.43)的配置:是将ssi 的servlet-mapping屏蔽掉了的,并且默认的ssi url-pattern为:*.shtml
<!--
<servlet-mapping>
<servlet-name>ssi</servlet-name>
<url-pattern>*.shtml</url-pattern>
</servlet-mapping>
-->
修改配置之后配置的ssi 的servlet-mapping 的url-pattern为*.html
并且:正常部署应用的tomcat 没有开放ssi filter以及 ssi servlet:
org.apache.catalina.core.StandardContext.filterStart Exception starting filter ssi
java.lang.SecurityException: Access to class [class org.apache.catalina.ssi.SSIFilter] is forbidden. It is a restricted class. A web application must be configured as privileged to be able to load it错误处理方式
当我在正常的tomcat里 把 ssi的 ssi filter以及 ssi servlet 开放起来之后,但是没有配置servlet-mapping时,再次启动tomcat,有报错信息:
org.apache.catalina.core.StandardContext.filterStart Exception starting filter ssi
java.lang.SecurityException: Access to class [class org.apache.catalina.ssi.SSIFilter] is forbidden. It is a restricted class. A web application must be configured as privileged to be able to load it
此时是什么都不显示的状态,服务直接是启动不起来的。 而当我把 :The mapping for the SSI servlet 的内容开启即:
再去启动tomcat时,发现依旧报错:
此时在conf下的 context.xml里 只要在context 里 加入:privileged=true
再次启动发现可以正常启动部署应用,浏览器中访问页面显示正常。
至此基本能确定: 是由于 web.xml里的 The mapping for the SSI servlet :servlet-mapping 的url-pattern影响了页面的显示导致提示找不到index.html页面,访问提示404 :
当设置 ssi的 servlet-mapping 的url-pattern为*.shtml的时候就可以正常加载index.html。
而如果不能修改 web.xml里的 ssi 的servlet-mapping 的url-pattern为*.shtml时 就直接将应用
xxx\WEB-INF\classes\static下的所有文件拷贝到xxx目录下就可以了。
*.shtml与*.html的区别是什么?
shtml跟html类似,也是一种用于网页设计的标记型语言,区别在于:html是一种纯静态的标记型语言,在html文档里面写的内容是什么,用户打开浏览器看到的就是什么,而shtml是一种半静态半动态的标记型语言,在shtml里面可以包含SSI命令,当用户在浏览器浏览shtml文档的时候,里面包含的SSI命令会被解析,然后再呈现内容给用户。
ssi命令指的是什么?
SSI指令基本格式
基本格式:<!--指令名称="指令参数">
如:<!--#include file="info.htm"-->
<!--#echo var="last_modified"-->
<!--include virtual="/includes/header.html"-->等
根据分析,出现org.apache.catalina.core.ApplicationContext.log ssi: Can't find file: /index.html
ERROR ErrorPageFilter Cannot forward to error page for request [/] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false
问题时,index.html页面内并没有类似的ssi指令:
唯有的:这两句话,看着也不是ssi指令。 但是 唯一的解释就是:
ssi 的servlet-mapping 的url-pattern为*.html时去找的是项目根目录下的页面,这就与应用本身需求读取的应用静态文件根目录static不一样,所以就找不到了。因此如果不改变url-pattern为*.shtml,把static下所有文件拷贝到应用根目录就可以访问了。
至于这是为什么? 我到现在都没想通... 就先记录一下吧