org.apache.catalina.core.ApplicationContext.log ssi: Can’t find file: /index.htmlERROR ErrorPageFil

The self-configured tomcat prompts an error message when deploying an application: 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

The phenomenon is shown in the figure below:

The result of this error is: the browser prompts 404 when accessing the project. Modify the configured tomcat version to 8.5.51

The strange thing is: the unconfigured tomcat can deploy the application normally,

This application is a spring boot project. The index.html in this project is located under WEB-INF\classes\static under the project; the page specification method of this index.html is: the root directory static of the static folder is read by default under the file.

The preliminary judgment is due to: a certain configuration of the configured tomcat affects the loading of this static page resource.

Let’s look at the error message again: org.apache.catalina.core.ApplicationContext.log ssi: Can’t find file: /index.html

What is ssi?

SSI is the abbreviation of Server Side Includes, which is a set of instructions embedded in HTML pages. Before returning the requested page (including SSI instructions), the server will process these instructions, replace the instructions with the processed results, and then return the page. This allows adding dynamically generated content to HTML pages.

There are two ways for tomcat to set ssi: find the web.xml file in the conf/ directory of the tomcat installation directory

1. SSI Servlet, that is, SSI servlet and servlet-mapping in web.xml
2. SSI filter, that is, SSI filter and filter-mapping in web.xml

In the current problem, the configuration of web.xml for ssi is:

<!-- 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>

According to the comparison with the web.xml configuration file of tomcat that normally deploys the application, it can be found that:

Normal web.xml configuration (tomcat 8.0.43) configuration: ssi servlet-mapping is shielded, and the default ssi url-pattern is: *.shtml

<!--
    <servlet-mapping>
        <servlet-name>ssi</servlet-name>
        <url-pattern>*.shtml</url-pattern>
    </servlet-mapping>
-->

After modifying the configuration, the url-pattern of the servlet-mapping of the ssi configured is *.html

And: tomcat for normal deployment of applications does not open ssi filter and 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 Error handling method

When I opened the ssi filter and ssi servlet of ssi in the normal tomcat, but did not configure servlet-mapping, I started tomcat again, and there was an error message:

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

At this time, nothing is displayed, The service cannot be started directly. And when I open the contents of: The mapping for the SSI servlet:

When I started tomcat again, I found that the error was still reported:

At this time, in the context.xml under conf, just add in the context: privileged=true

Start again and find that the deployment application can be started normally, and the access page in the browser is displayed normally.

So far, it can be basically determined: It is because of The mapping for the SSI servlet in web.xml: the url-pattern of servlet-mapping affects the display of the page, resulting in a prompt that the index.html page cannot be found, and the access prompt 404:

When setting the url-pattern of ssi’s servlet-mapping to *.shtml, index.html can be loaded normally.

If you cannot modify the url-pattern of the ssi servlet-mapping in web.xml to *.shtml, apply it directly

Just copy all the files under xxx\WEB-INF\classes\static to the xxx directory.

What is the difference between

*.shtml and *.html?

shtml is similar to html, and it is also a markup language for web design. The difference is that html is a purely static markup language. What is written in the html document is what the user sees when they open the browser , and shtml is a semi-static and semi-dynamic markup language. SSI commands can be included in shtml. When the user browses the shtml document in the browser, the SSI commands contained in it will be parsed, and then the content will be presented to the user.

What does the ssi command refer to?

SSICommand basic format
Basic format:

etc.

According to the analysis, org.apache.catalina.core.ApplicationContext.log ssi: Can’t find file: /index.html appears
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

When the problem arises, there is no similar ssi instruction in the index.html page:

Only: these two sentences, see This is not an ssi command either. But the only explanation is:

When the url-pattern of ssi’s servlet-mapping is *.html, it is looking for the page under the root directory of the project, which is different from the root directory static of the application static file that the application itself needs to read, so it cannot be found arrive. Therefore, if you do not change the url-pattern to *.shtml, you can access it by copying all the files under static to the root directory of the application.

As for why? I haven’t figured it out yet… just record it first