日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

tomcat ssi配置及升级导致ssi include错误问题解决

發布時間:2025/7/14 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 tomcat ssi配置及升级导致ssi include错误问题解决 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近tomcat升級版本時,遇到了ssi解析的問題,記錄下解決的過程,還有tomcat ssi配置的要點。

tomcat 配置SSI的兩種方式

Tomcat有兩種方式支持SSI:Servlet和Filter。

SSIServlet

通過Servlet,org.apache.catalina.ssi.SSIServlet,默認處理”*.shtml”的URL。

配置方式:

修改tomcat的 conf/web.xml文件,去掉下面配置的注釋:

<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> </init-param> <load-on-startup>4</load-on-startup> </servlet> <servlet-mapping> <servlet-name>ssi</servlet-name> <url-pattern>*.shtml</url-pattern> </servlet-mapping>

SSIFilter

通過Filter,org.apache.catalina.ssi.SSIFilter,默認處理”*.shtml”的URL。

配置方式:

修改tomcat的 conf/web.xml文件,打開去掉下面配置的注釋:

<filter><filter-name>ssi</filter-name> <filter-class> org.apache.catalina.ssi.SSIFilter </filter-class> <init-param> <param-name>contentType</param-name> <param-value>text/x-server-parsed-html(;.*)?</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> </init-param> </filter> <filter-mapping> <filter-name>ssi</filter-name> <url-pattern>*.shtml</url-pattern> </filter-mapping>

注意事項

注意:兩種配置方式最好不要同時打開,除非很清楚是怎樣配置的。

另外,在Tomcat的conf/context.xml里要配置privileged=”true”,否則有些SSI特性不能生效。

<Context privileged="true">
  • 1
  • 1

歷史代碼里處理SSI的辦法

在公司的歷史代碼里,在一個公共的jar包里通過自定義一個EnhancedSSIServlet,繼承了Tomcat的org.apache.catalina.ssi.SSIServlet來實現SSI功能的。

@WebServlet(name="ssi",initParams={@WebInitParam(name="buffered", value="1"), @WebInitParam(name="debug", value="0"), @WebInitParam(name="expires", value="666"), @WebInitParam(name="isVirtualWebappRelative", value="0"), @WebInitParam(name="inputEncoding", value="UTF-8"), @WebInitParam(name="outputEncoding", value="UTF-8") }, loadOnStartup=1, urlPatterns={"*.shtml"}, asyncSupported=true) public class EnhancedSSIServlet extends SSIServlet {

其中@WebServlet是Servlet3.0規范里的,所以使用到web-common的web項目的web.xml文件都要配置為3.0版本以上,例如:

<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> </web-app>

Tomcat是啟動Web應用時,會掃描所有@WebServlet的類,并初始化。

所以在使用到歷史代碼的項目都只能使用Tomcat服務器,并且不能在tomcat的conf/web.xml里打開SSI相關的配置。

Tomcat版本升級的問題

Tomcat版本從7.0.57升級到7.0.59過程中,出現了無法解析SSI include指令的錯誤:

SEVERE: #include--Couldn't include file: /pages/test/intelFilter.shtml java.io.IOException: Couldn't get context for path: /pages/test/intelFilter.shtmlat org.apache.catalina.ssi.SSIServletExternalResolver.getServletContextAndPathFromVirtualPath(SSIServletExternalResolver.java:422)at org.apache.catalina.ssi.SSIServletExternalResolver.getServletContextAndPath(SSIServletExternalResolver.java:465)at org.apache.catalina.ssi.SSIServletExternalResolver.getFileText(SSIServletExternalResolver.java:522) at org.apache.catalina.ssi.SSIMediator.getFileText(SSIMediator.java:161) at org.apache.catalina.ssi.SSIInclude.process(SSIInclude.java:50) at org.apache.catalina.ssi.SSIProcessor.process(SSIProcessor.java:159) at com.test.webcommon.servlet.EnhancedSSIServlet.processSSI(EnhancedSSIServlet.java:72) at org.apache.catalina.ssi.SSIServlet.requestHandler(SSIServlet.java:181) at org.apache.catalina.ssi.SSIServlet.doPost(SSIServlet.java:137) at javax.servlet.http.HttpServlet.service(HttpServlet.java:646) at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748) at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:604) at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:543) at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:954) at org.apache.jsp.pages.lottery.jczq.index_jsp._jspService(index_jsp.java:107) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:395) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:339) at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)

仔細查看源代碼后,發現不能處理的include指令代碼如下:

<!--#include virtual="/pages/test/intelFilter.shtml"-->

經過對比調試Tomcat的代碼,發現是在7.0.58版本時,改變了處理URL的方法,關鍵的處理函數是

org.apache.catalina.core.ApplicationContext.getContext( String uri)

在7.0.57版本前,Tomcat在處理處理像/pages/test/intelFilter.shtml這樣的路徑時,恰好循環處理了”/”字符,使得childContext等于StandardContext,最終由StandardContext處理了/pages/test/intelFilter.shtml的請求。

這個代碼實際上是錯誤的,不過恰好處理了include virtual的情況。

在7.0.58版本修改了處理uri的代碼,所以在升級Tomcat到7.0.59時出錯了。

7.0.57版的代碼:?
https://svn.apache.org/repos/asf/tomcat/tc7.0.x/tags/TOMCAT_7_0_57/java/org/apache/catalina/core/ApplicationContext.java

/*** Return a <code>ServletContext</code> object that corresponds to a* specified URI on the server. This method allows servlets to gain* access to the context for various parts of the server, and as needed* obtain <code>RequestDispatcher</code> objects or resources from the* context. The given path must be absolute (beginning with a "/"),* and is interpreted based on our virtual host's document root.** @param uri Absolute URI of a resource on the server*/ @Override public ServletContext getContext(String uri) { // Validate the format of the specified argument if ((uri == null) || (!uri.startsWith("/"))) return (null); Context child = null; try { Host host = (Host) context.getParent(); String mapuri = uri; while (true) { child = (Context) host.findChild(mapuri); if (child != null) break; int slash = mapuri.lastIndexOf('/'); if (slash < 0) break; mapuri = mapuri.substring(0, slash); } } catch (Throwable t) { ExceptionUtils.handleThrowable(t); return (null); } if (child == null) return (null); if (context.getCrossContext()) { // If crossContext is enabled, can always return the context return child.getServletContext(); } else if (child == context) { // Can still return the current context return context.getServletContext(); } else { // Nothing to return return (null); } }

7.0.58的代碼:?
https://svn.apache.org/repos/asf/tomcat/tc7.0.x/tags/TOMCAT_7_0_58/java/org/apache/catalina/core/ApplicationContext.java

那么正確的處理辦法是怎樣的?

仔細查看Tomcat的SSI配置的說明文檔,發現有一個isVirtualWebappRelative的配置,而這個配置默認是false的。

isVirtualWebappRelative - Should "virtual" SSI directive paths be interpreted as relative to the context root, instead of the server root? Default false.

**也就是說,如果要支持“#include virtual=”/b.shtml”絕對路徑這種指令,就要配置isVirtualWebappRelative為true。?
但是tomcat默認的SSI配置,以及上面的EnhancedSSIServlet類默認都配置isVirtualWebappRelative為false。**

因此,把EnhancedSSIServlet類里的isVirtualWebappRelative配置為true,重新測試,發現已經可以正常處理”#include virtual=”/b.shtml”指令了。

相關的邏輯處理的代碼在org.apache.catalina.ssi.SSIServletExternalResolver.getServletContextAndPathFromVirtualPath( String virtualPath):

protected ServletContextAndPath getServletContextAndPathFromVirtualPath(String virtualPath) throws IOException {if (!virtualPath.startsWith("/") && !virtualPath.startsWith("\\")) { return new ServletContextAndPath(context, getAbsolutePath(virtualPath)); } String normalized = RequestUtil.normalize(virtualPath); if (isVirtualWebappRelative) { return new ServletContextAndPath(context, normalized); } ServletContext normContext = context.getContext(normalized); if (normContext == null) { throw new IOException("Couldn't get context for path: " + normalized); }

總結

之前的EnhancedSSIServlet類的配置就不支持”#include virtual=”/b.shtml”,這種絕對路徑的SSI指令,而以前版本的Tomcat因為恰好處理了”/test.shtml”這種以”/”開頭的url,因此以前版本的Tomcat沒有報錯。而升級后的Tomcat修正了代碼,不再處理這種不合理的絕對路徑請求了,所以報“ Couldn’t get context for path”的異常。

把tomcat的ssi配置里的isVirtualWebappRelative設置為true就可以了。

最后,留一個小問題:

tomcat是如何知道處理*.jsp請求的?是哪個servlet在起作用?

分類: JAVA 好文要頂 關注我 收藏該文 左正
關注 - 29
粉絲 - 126 +加關注 0 0 ? 上一篇:配置tomcat讓shtml嵌套文件顯示
? 下一篇:IntelliJ IDEA部署tomcat時Edit Configuration無artifact選項
posted @ 2017-03-03 19:19 左正 閱讀(167) 評論(0) 編輯 收藏 刷新評論刷新頁面返回頂部 (評論功能已被禁用) 【推薦】超50萬VC++源碼: 大型工控、組態\仿真、建模CAD源碼2018!
【推薦】騰訊云新用戶域名搶購1元起,抓緊搶購
最新IT新聞:
· 阮一峰:加密貨幣的本質
· ofo被曝訂單較峰值跌六成 賬戶現金僅能支撐一個月
· 途牛宣布一億美元股票回購計劃及CTO任命
· 我們幫你劃了一份微信公開課PRO的重點
· iPhone 4S起死回生,可降級至iOS 6.1.3
? 更多新聞... 本文轉自左正博客園博客,原文鏈接:http://www.cnblogs.com/soundcode/p/6498147.html,如需轉載請自行聯系原作者

總結

以上是生活随笔為你收集整理的tomcat ssi配置及升级导致ssi include错误问题解决的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。