- PR -

strutsのdtdファイルが読み込めていない?

1
投稿者投稿内容
Mountain
会議室デビュー日: 2004/07/20
投稿数: 11
投稿日時: 2007-08-31 14:39
いつもお世話になっています。
現在strutsを用いてWebアプリの開発を行っているのですが、デプロイ時にエラーが発生してしまい、
その原因がわからず苦心しております。ご教授よろしくお願いします。

【環境】
eclipse3.2
JDK 1.4.11
Tomcat5.0
struts1.2.9
spring 2.0
hibernate3.0

【前提】
@struts-config_1_2.dtdのアクション要素に"hogeValidate"を追加したファイル
struts-config_1_2_hoge.dtdを作成し、struts-configの<!DOCTYPE〜に記述
Aactionの要素に"hogeValidate"を追加

<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
"struts-config_1_2_hoge.dtd">

<struts-config>
<action-mappings type="hoge.ActionMapping">
<action path="/hoge"
name="hogeForm"
type="org.springframework.web.struts.DelegatingActionProxy"
validate="false"
hogeValidate="false"
scope="request">
<forward name="success" path="hoeg.jsp"/>
</action>
</action-mappings>
</struts-config>

【現象】
@デプロイ時に以下のエラーメッセージが発生する。
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

ERROR Parse Error at line 273 column 36: Attribute "hogeValidate" must be declared for element type "action". (org.apache.commons.digester.Digester.error())
org.xml.sax.SAXParseException: Attribute "hogeValidate" must be declared for element type "action".
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at org.apache.xerces.util.ErrorHandlerWrapper.error(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.dtd.XMLDTDValidator.addDTDDefaultAttrsAndValidate(Unknown Source)
at org.apache.xerces.impl.dtd.XMLDTDValidator.handleStartElement(Unknown Source)
at org.apache.xerces.impl.dtd.XMLDTDValidator.startElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.commons.digester.Digester.parse(Digester.java:1572)
at org.apache.struts.action.ActionServlet.parseModuleConfigFile(ActionServlet.java:738)
at org.apache.struts.action.ActionServlet.initModuleConfig(ActionServlet.java:687)
at org.apache.struts.action.ActionServlet.init(ActionServlet.java:333)
at javax.servlet.GenericServlet.init(GenericServlet.java:211)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1029)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:862)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4013)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4357)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1083)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:789)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1083)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:478)
at org.apache.catalina.core.StandardService.start(StandardService.java:480)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:2313)
at org.apache.catalina.startup.Catalina.start(Catalina.java:556)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:287)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:425)


Aだたし、DOCTYPEの "DTD Struts Configuration"を1.2→1.3に変更するとエラーは解消される。
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
"struts-config_1_2_hoge.dtd">

何とかエラーを回避できるのですが何故そうなるのか?
そもそもこの対応で問題ないのかわかりません。
若輩もの故、不躾な質問ですが、ご教授いただけると幸いです。

以上、よろしくお願いします。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-08-31 16:40
Digesterがパースの際に利用するDTDファイルの実体は、
org/apache/struts/resources/以下に存在します。
また、そのDTDファイルへの参照をActionServletの中で設定しています。
(DTDはjarの中に含まれています。)

したがってPUBLIC IDで指定されている名前が
"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
の場合、その実体が参照されますので、パースエラーとなっているのでしょう。

Struts1.2.9には1.3のDTDに対する定義が行われていないので、
DTDによるバリデーションが行われないために、エラーとならないのでしょう。
(この辺は未確認ですが、挙動からするとそういうことなんでしょう・・・)

回避策としては、
・ActionServletを継承してinitConfigDigester()をオーバーライド
・initConfigDigesterを以下のようにする
・web.xmlにそのクラスを記述する
・struts-config.xmlのDOCTYPEを書き換える
コード:
protected Digester initConfigDigester() throws ServletException {
    Digester digester = super.initConfigDigester();
    URL url = getClass().getClassLoader().getResource("<DTDのクラスパス上のパス>");
    digester.register("<好きなPUBLIC ID>", url.toString());
    return digester;    
}


という感じになります。
DTDファイルはクラスパス上に配置する必要があります。
どのようなパスの書き方をするのかは、ActionServletのコードを読めば分かると思います。
PUBLIC IDはお好きなIDにしてください。
Mountain
会議室デビュー日: 2004/07/20
投稿数: 11
投稿日時: 2007-08-31 19:11
お世話になります。
ご回答ありがとうございます。

しばらく席をはずしていたため返信が遅れてしましました。
申し訳ありません。
早速ためしてみたいと思います。
1

スキルアップ/キャリアアップ(JOB@IT)