Cómo fusionar el fragmento web.xml precompilado de jsp con el web.xml principal usando Ant

StackOverflow https://stackoverflow.com/questions/162079

Pregunta

tenemos lo de siempre web.xml para nuestra aplicación web que incluye algunos archivos jsp y etiquetas jsp.Quiero pasar a utilizar jsp precompilados.Tengo la precompilación en la compilación correctamente, genera el fragmento web.xml y ahora quiero fusionar el fragmento en el web.xml principal.

Hay un incluir directiva de tipo para web.xml eso me permitirá incluir el fragmento.

Lo ideal sería dejar las cosas como están para DEV, ya que es útil cambiar los JSP sobre la marcha y ver los cambios inmediatamente, pero luego, para UAT/PROD, los JSP se precompilarán y, por lo tanto, funcionarán más rápido.

¿Fue útil?

Solución

Utilizo las tareas ANT de jaspe de Tomcat en mi proyecto, que precompila los JSP en servlets y agrega las nuevas asignaciones de servlets al web.xml original. En las compilaciones de DEV, simplemente omita este paso e implemente los JSP sin precompilar y modificar el 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>

Si ya tiene la compilación JSP funcionando y solo desea fusionar los archivos web.xml, se podría escribir un XSLT simple para agregar elementos seleccionados (como las asignaciones de servlet) de la web recién generada, xml a su original.

Otros consejos

Doh: hay una opción en la tarea jasper2 para fusionar automáticamente el fragmento en el web.xml principal - 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" />

Me pregunto qué tan buena es la fusión ...

Es molesto que aún tengas que generar el fragmento, aunque no sea necesario después de esta tarea.

Debido a que el fragmento generado no es un archivo XML válido (después de todo, es un fragmento), no es posible utilizar XSLT directamente.Por otro lado, no es necesario.Aquí tienes un truco sencillo que te dará exactamente lo que necesitas.

En su archivo web.xml inserte un comentario XML <!-- @JSPS_MAP@ --> entre <servlet> y <servlet-mapping> elementos, p.e.

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

Luego use un filtro de token para reemplazar @JSPS_MAP@ etiqueta con contenido generado.

<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=" --&gt; ${generated.web.xml.fragment} &lt;!-- "
    />
  </filterset>
</copy>

Este enfoque tiene la ventaja de que el archivo web.xml original es completamente válido (una etiqueta está oculta en el comentario), pero le brinda control total de dónde y cuándo se insertará el fragmento generado.

Entonces, para la compilación DEV, simplemente copie ${orig-web-content.dir}/WEB-INF/web.xml a ${generated-web-content.dir}/WEB-INF/web.xml sin filtrar.

Existe la tarea de hormiga jasper2 que otros han notado. Pensé en mencionar algunas otras opciones que he encontrado.

Uno es la tarea de hormigas webxmlmerge de cactus, que utiliza org.codehaus.cargo.module.webapp.WebXmlMerger

Otra sería usar JAXB para manipular el web.xml; La dtd-schemas-generator demo de Sebastien Dionne hace esto . Sin embargo, no estoy seguro de cuál es la licencia.

después de haber considerado estas opciones, creo que voy a usar la tarea hormiga XSLT .

En su archivo web.xml si tiene etiquetas para especificar dónde comienza y termina la fusión, el indicador addWebXmlMappings generará el archivo correctamente para usted. Las etiquetas son: <! - Comienzan las asignaciones de servlets JSPC - > y <! - Las asignaciones de servlet JSPC finalizan - > después de hacer esto a mi web.xml, ¡todo funcionó de maravilla! (Tengo que mirar el código de org.apcahe.jasper.JspC para ver cómo se implementó)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top