如何使用Ant将JSP预编译的web.xml片段与主web.xml合并
对于我们的Web应用程序,我们具有通常的web.xml,其中包括一些jsp和jsp标记文件。我想切换到使用预编译的jsp。我在构建ok中进行了预编译,它生成了web.xml片段,现在我想将该片段合并到主要的web.xml中。
是否有web.xml的包含类型指令,可让我包含该片段。
理想情况下,我将对DEVas保持现状,因为它可以即时更改jsp并立即查看更改,但是对于UAT / PROD,将对jsp进行预编译,从而使其工作更快。
解决方案
难道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" />
我不知道合并有多好...
令人烦恼的是,我们仍然需要生成片段,即使在此任务之后不需要它也是如此。
我在项目中使用了Tomcat jasper ANT任务,这些任务将JSP预编译为servlet,并将新的servlet映射添加到原始的web.xml中。在DEV构建中,只需跳过此步骤并部署JSP,而无需预编译和修改web.xml。
<?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中的选定元素(例如servlet映射)添加到原始文件中。
由于生成的片段不是有效的XML文件(毕竟是片段),因此无法直接使用XSLT。另一方面,我们不必这样做。这是一个简单的技巧,它将为我们提供所需的确切信息。
在web.xml文件中的<servlet>和<servlet-mapping>元素之间插入XML注释<!-@ JSPS_MAP @->`,例如
<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复制到
$ {generation-web-content.dir} / WEB-INF / web.xml`即可, 。
还有其他人已经提到过的jasper2 ant任务。我以为我会提到我发现的其他几个选择。
一个是仙人掌的webxmlmerge ant任务,它使用org.codehaus.cargo.module.webapp.WebXmlMerger
另一个方法是使用JAXB来操纵web.xml。 Sebastien Dionne的dtd-schemas-generator演示可以做到这一点。虽然不确定许可证是什么。
在考虑了这些选项之后,我想我将使用ant XSLT任务。
在web.xml文件中,如果我们有用于指定合并开始和结束位置的标记,则addWebXmlMappings标志将为我们正确生成文件。标签是:
<!-JSPC servlet映射开始->
和
<!-JSPC servlet映射结束->
在对我的web.xml执行此操作之后,一切都像个魅力! (我必须查看org.apcahe.jasper.JspC的代码才能看到它是如何实现的)