Antを使用してjspプリコンパイル済みweb.xmlフラグメントをメインweb.xmlとマージする方法
質問
jspおよびjspタグファイルを含むWebアプリケーション用の通常の web.xml があります。プリコンパイルされたjspの使用に切り替えたい。ビルドでプリコンパイルが発生し、web.xmlフラグメントが生成されます。次に、フラグメントをメインweb.xmlにマージします。
フラグメントを含めることができる web.xml の include タイプディレクティブがあります。
理想的には、DEVの場合はそのままにしておきます。JSPをオンザフライで変更してすぐに変更を確認するのに便利ですが、UAT / PRODの場合は、JSPがプリコンパイルされるため、高速に動作します。
解決
TomcatジャスパーANTタスクを使用しますプロジェクト。JSPをサーブレットにプリコンパイルし、新しいサーブレットマッピングを元のweb.xmlに追加します。 DEVビルドでは、この手順をスキップして、web.xmlをプリコンパイルおよび変更せずにJSPをデプロイします。
<?xml version="1.0"?>
<project name="jspc" basedir="." default="all">
<import file="${build.appserver.home}/bin/catalina-tasks.xml"/>
<target name="all" depends="jspc,compile"></target>
<target name="jspc">
<jasper
validateXml="false"
uriroot="${build.war.dir}"
webXmlFragment="${build.war.dir}/WEB-INF/generated_web.xml"
addWebXmlMappings="true"
outputDir="${build.src.dir}" />
</target>
<target name="compile">
<javac destdir="${build.dir}/classes"
srcdir="${build.src.dir}"
optimize="on"
debug="off"
failonerror="true"
source="1.5"
target="1.5"
excludes="**/*.smap">
<classpath>
<fileset dir="${build.war.dir}/WEB-INF/classes">
<include name="*.class" />
</fileset>
<fileset dir="${build.war.lib.dir}">
<include name="*.jar" />
</fileset>
<fileset dir="${build.appserver.home}/lib">
<include name="*.jar" />
</fileset>
<fileset dir="${build.appserver.home}/bin">
<include name="*.jar"/>
</fileset>
</classpath>
<include name="**" />
<exclude name="tags/**"/>
</javac>
</target>
<target name="clean">
<delete>
<fileset dir="${build.src.dir}"/>
<fileset dir="${build.dir}/classes/org/apache/jsp"/>
</delete>
</target>
</project>
すでにJSPコンパイルが機能していて、web.xmlファイルをマージするだけの場合は、単純なXSLTを記述して、新しく生成されたweb、xmlから選択した要素(サーブレットマッピングなど)をオリジナルに追加できます。
他のヒント
Doh-jasper2タスクには、フラグメントをメインweb.xmlに自動マージするオプションがあります- addWebXmlMappings
<jasper2
validateXml="false"
uriroot="${web.dir}"
addWebXmlMappings="true"
webXmlFragment="${web.dir}/WEB-INF/classes/jasper_generated_web.xml"
outputDir="${web.dir}/WEB-INF/jsp-src" />
マージがどれほど優れているのだろうか...
迷惑なことに、このタスクの後で不要なフラグメントであっても、フラグメントを生成する必要があります。
生成されたフラグメントは有効なXMLファイルではないため(結局フラグメントです)、XSLTを直接使用することはできません。一方、あなたはする必要はありません。必要なものを正確に提供する簡単なトリックを次に示します。
web.xmlファイルで、<!-- @JSPS_MAP@ -->
要素と<servlet>
要素の間にXMLコメント<servlet-mapping>
を挿入します。例:
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>my.servlets.MyServlet</servlet-class>
<servlet>
<!-- @JSPS_MAP@ -->
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/my-servlet</url-pattern>
</servlet-mapping>
次に、トークンフィルターを使用して、@JSPS_MAP@
タグを生成されたコンテンツに置き換えます。
<loadfile
property="generated.web.xml.fragment"
srcFile="${generated.fragment.file}"
/>
<copy file="${orig-web-content.dir}/WEB-INF/web.xml"
toFile="${generated-web-content.dir}/WEB-INF/web.xml"
>
<filterset>
<filter token="JSPS_MAP"
value=" --> ${generated.web.xml.fragment} <!-- "
/>
</filterset>
</copy>
このアプローチには、元のweb.xmlファイルが完全に有効(タグがコメント内に隠されている)であるという利点がありますが、生成されたフラグメントを挿入する場所とタイミングを完全に制御できます。
したがって、DEVビルドの場合は、フィルタリングせずに${orig-web-content.dir}/WEB-INF/web.xml
を${generated-web-content.dir}/WEB-INF/web.xml
にコピーするだけです。
他の人が指摘した jasper2 antタスクがあります。私が見つけた他のいくつかのオプションについて言及すると思いました。
1つはorg.codehaus.cargo.module.webapp.WebXmlMergerを使用するcactusの webxmlmerge antタスクです。
別の方法は、 JAXB を使用してweb.xmlを操作することです。 Sebastien Dionneの dtd-schemas-generator デモはこれを行います。ただし、ライセンスが何なのかわかりません。
fwiwはこれらのオプションを検討したので、ant XSLT タスクを使用するつもりだと思います。
web.xmlファイルで、マージの開始および終了の場所を指定するタグがある場合、addWebXmlMappingsフラグはファイルを正しく生成します。タグは次のとおりです。 <!> lt;!-JSPCサーブレットマッピングの開始-<!> gt; そして <!> lt;!-JSPCサーブレットマッピングの終了-<!> gt; これを私のweb.xmlに行った後、すべてが魅力のように機能しました! (org.apcahe.jasper.JspCのコードを見て、この実装方法を確認する必要があります)