Mejores prácticas para compartir código de nivel web (controladores y JSP) entre aplicaciones web similares

Estoy trabajando en reescribir algunas aplicaciones web antiguas. Hay dos en particular que son muy, muy similares, pero no comparten código hoy y mi objetivo es solucionarlo.

Los proyectos se están reescribiendo con Maven, Spring MVC y Sitemesh.

El código de nivel de modelo es lo suficientemente fácil de compartir mediante JAR. Pero no conozco ninguna buena manera de compartir código común de nivel web (JSP y controladores) entre aplicaciones similares.

Aquí hay algunos antecedentes. Estas aplicaciones son tiendas web. Una es una tienda normal (piense en amazon.com) en la que un usuario puede iniciar sesión, buscar productos, agregar a un carrito de compras y pagar. El otro es básicamente lo mismo, solo que es un sitio impactante. Las partes de navegación del producto y carrito de compras son idénticas. Iniciar sesión y pagar, sin embargo, son completamente diferentes.

Estoy simplificando demasiado, pero es suficiente para ilustrar el problema. Hay una porción significativa de código de nivel web en las secciones de navegación y carrito de compras del producto que deberían poder compartirse entre los dos.

No creo que sea posible simplemente tener el mismo archivo WAR ejecutándose como "modo" basado en una variable de entorno o en configuraciones de una base de datos diferente. Una de las diferencias es una configuración de Spring Security completamente diferente. También sería preferible dejar fuera del escaneo de componentes los controladores de inicio de sesión y salida del otro sitio para que nadie pueda de alguna manera cruzar al incorrecto con la manipulación de URL.

Originalmente comencé a usar Perfiles de Maven y a filtrar para mantener dos conjuntos de configuración diferentes (web.xml, spring configs, etc.) en el mismo proyecto WAR. Según el perfil de Maven seleccionado, el WAR resultante se construye con un conjunto de configuración diferente (y un nombre diferente para mayor claridad). Esto viola el principio de Maven de que un pom produce un artefacto.

¿Hay una mejor manera de hacer esto? ¿Qué pasa con las superposiciones WAR de Maven? Veo personas hablando sobre el uso de superposiciones para compartir recursos comunes como CSS, JS, imágenes e incluso algunos JSP comunes. Pero no veo que nadie mencione compartir clases como Controllers de esta manera.

Podría llevar las clases de Controlador a los JAR, pero lógicamente parece que deberían quedarse con sus respectivos JSP. Y los JSP tampoco pueden ser empujados hacia abajo a los JAR (¿verdad?).

También pensé en convertirlo en un EAR que contuviera múltiples archivos WAR: un WAR para la experiencia de compra común y otro WAR para el inicio de sesión y el pago apropiados. Creo que la sesión se puede compartir entre dos WAR en el mismo EAR, pero no estoy seguro de si funciona bien con los beans de alcance de sesión de Spring. Escuché que realmente no están almacenados en la sesión. También tendría que averiguar qué hacer con los decoradores de Sitemesh que se usan para el encabezado / pie de página. La misma configuración de Sitemesh y sus recursos tendrían que copiarse en ambos WAR, ¿verdad? Entonces, al final, el artefacto WAR de compras aún sería diferente en cada circunstancia.

Tengo que creer que otras personas han lidiado con esto antes. ¿Estoy pensando en eso de manera incorrecta? ¿Hay una solución común para este tipo de cosas?

Respuesta 1

Buen trabajo luchando contra copiar y pegar. ¿Por qué dices que es difícil compartir JSP? Puede copiarlos de un jar compartido usando el complemento de dependencia de Maven:

 <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-dependency-plugin</artifactId>
         <version>2.4</version>
         <executions>
           <execution>
             <id>unpack</id>
             <phase>package</phase>
             <goals>
               <goal>unpack</goal>
             </goals>
             <configuration>
               <artifactItems>
                 <artifactItem>
                   <groupId>com.example</groupId>
                   <artifactId>webapp-common</artifactId>
                   <version>1.0-SNAPSHOT</version>
                   <outputDirectory>[target jsp directory]</outputDirectory>
                   <includes>**/*.jsp</includes>
                 </artifactItem>
               </artifactItems>
             </configuration>
           </execution>
         </executions>
       </plugin>
Respuesta: 2

Mi opción preferida en estos casos es poner todos los archivos relacionados (controladores, js, imágenes ...) en un jar. Pero el problema aquí es el uso de archivos JSP : no hay una manera fácil de usarlos si están en un jar. Pero con otras tecnologías de visualización como Velocity o Freemarker, esto es posible de una manera fácil, entre otras ventajas. No sé si esto puede llevarlo a demasiado trabajo, pero para un nuevo proyecto con estas necesidades es la mejor opción.

Respuesta: 3

Estamos usando Subversion aquí, y usamos svn: externals (algo así como enlaces simbólicos) para compartir cierto código común (principalmente archivos .jsp) entre proyectos. Funciona bastante bien, estábamos usando OC4J, que en realidad tiene una forma de compartir .jsp entre múltiples proyectos, pero dado que actualmente nos estamos moviendo hacia Tomcat (o algo más), quería encontrar una forma agnóstica de contenedores para hacerlo.

Respuesta: 4

¿Debo usar "_activity = this;"? He visto _actividad referenciada muchas veces en el código de muestra. Entonces, arbitrariamente decidí que parecía una buena práctica y he estado usando todo mi código por un tiempo ...

He leído que una sal que se va a usar debe tener la misma longitud que la contraseña hash, ¿cuál es el razonamiento detrás de esto? ¿Aumentará la protección con contraseña? Lo he leído aquí: ...

Estoy intentando construir un servicio web alojado en Glassfish que suplante (para pruebas de desarrollo) un servicio web alojado en WCF. Tengo el WSDL del servicio alojado WCF, y puedo construir el ...

Pienso en un patrón de diseño Singleton común: clase pública Singleton {instancia Singleton estática privada; private Singleton () {} public static Singleton getInstance () {if (instancia == ...