在类似的Web应用程序之间共享Web层代码(控制器和JSP)的最佳实践
问题内容:
我正在重写一些老化的Web应用程序。特别是有两个非常非常相似,但是今天没有共享任何代码,我打算解决这个问题。
正在使用Maven,Spring MVC和Sitemesh重写项目。
模型层代码很容易使用JAR共享。但是我不知道在相似的应用程序之间共享通用Web层代码(JSP和控制器)的任何好方法。
这是一些背景。这些应用是网上商店。一个是普通商店(think
amazon.com),用户可以登录该商店,搜索产品,添加到购物车并进行结帐。另一个基本上是相同的,只是它是一个打孔站点。产品浏览和购物车部分相同。但是,登录和结帐完全不同。
我简化了,但这足以说明问题。在产品浏览和购物车部分中,有很大一部分网络层代码应该可以在两者之间共享。
我认为不可能仅仅基于环境变量或来自不同数据库的设置而将与“模式”相同的WAR文件运行。差异之一是完全不同的Spring
Security配置。最好还是将另一个站点的登录和签出控制器放在组件扫描之外,这样没人可以通过URL操作以某种方式越过错误的站点。
我最初开始使用Maven配置文件并进行过滤,以将两个不同的配置集(web.xml,spring
config等)保留在同一WAR项目中。根据选择的Maven配置文件,将使用不同的配置集(为清楚起见使用不同的名称)构建生成的WAR。这违反了一个pom产生一个工件的Maven原则。
有一个更好的方法吗?Maven
WAR叠加层如何?我看到有人在谈论使用叠加来共享通用资源,例如CSS,JS,图像,甚至某些通用JSP。但是我看不到有人提到过像Controllers这样的类共享。
我可以将Controller类推到JAR,但从逻辑上讲,似乎它们应该保留在各自的JSP中。而且,JSP也不能下推到JAR(对吗?)。
我还考虑过使其成为一个包含多个WAR文件的EAR-
一个WAR用于普通的购物体验,另一个WAR用于适当的登录和结帐。我相信可以在同一个EAR中的两个WAR之间共享会话,但是我不确定它是否可以与Spring的会话范围bean配合使用。我听说它们没有真正存储在会话中。我还必须弄清楚如何处理用于页眉/页脚的Sitemesh装饰器。需要将相同的Sitemesh配置及其资源复制到两个WAR中,对吗?因此,最终,购物WAR工件在每种情况下都将有所不同。
我必须相信其他人以前已经处理过这个问题。我是否以错误的方式思考?对于这种事情是否有通用的解决方案?
问题答案:
做好与复制粘贴作斗争的工作。为什么说很难共享JSP?您可以使用maven依赖插件将它们复制到共享jar中:
<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>