在类似的Web应用程序之间共享Web层代码(控制器和JSP)的最佳实践

9

我正在重写一些老化的网络应用程序。其中有两个非常相似,但今天没有共享代码,我想解决这个问题。

使用Maven、Spring MVC和Sitemesh重写项目。

使用JAR文件轻易共享模型层代码。但我不知道如何在类似的应用程序之间共享通用的Web层代码(JSP和控制器)。

以下是一些背景信息。这些应用程序是网络商店。一个是普通商店(类似于amazon.com),用户可以登录、搜索产品、添加到购物车并结账。另一个基本相同,只是它是 punchout 站点。浏览产品和购物车部分完全相同。但是,登录和结账是完全不同的。

我简单地阐述了这个问题。产品浏览和购物车部分有很大一部分Web层代码应该能够在两者之间共享。

我不认为可能简单地运行相同的WAR文件作为基于环境变量或来自不同数据库的设置的“模式”。其中一个区别是完全不同的Spring Security配置。最好也将另一个站点的登录和结账控制器排除在组件扫描之外,以免通过URL操作某人错误地跨越到其他站点。

我最初使用Maven配置文件和过滤器来保留两个不同的配置集(web.xml、Spring配置等)在同一个WAR项目中。基于所选的Maven配置文件,生成的WAR将使用不同的配置集构建(并为清晰起见使用不同的名称)。这违反了Maven原则,即一个POM生成一个构件。

有更好的方法吗?Maven WAR Overlays呢?我看到人们谈论使用覆盖来共享常见资源,如CSS、JS、图像,甚至一些常见的JSP。但是我没有看到有人提到可以通过此方式共享控制器等类。

我可以把控制器类下放到JAR包中,但从逻辑上讲,它们应该与各自的JSP保持在一起。而且JSP也不能被下放到JAR包中(对吗?)。

我还考虑将其制作成一个EAR文件,其中包含多个WAR文件——一个WAR用于共同的购物体验,另一个WAR用于相应的登录和结账。我相信同一EAR中的两个WAR之间可以共享会话,但我不确定它是否与Spring的会话范围bean兼容。我听说它们并没有真正存储在会话中。我还需要想出如何处理用于页眉/页脚的Sitemesh装饰器。相同的Sitemesh配置及其资源需要复制到两个WAR中,对吗?因此,最终,购物WAR构件在每种情况下仍将有所不同。

我相信其他人以前也处理过这个问题。我想错了吗?这种情况是否有通用解决方案?

4个回答

1
干得好,打击复制粘贴行为是正确的。您为什么说共享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>

这是一个不错的技巧,我可能会采用它,因为我看不到我们会放弃Maven。唯一显而易见的缺点是,如果开发人员从JAR文件中复制JSP,则无法再实时更新。需要通过IDE进行重建和重新部署才能看到简单的编辑。我怀疑是否有什么办法可以解决这个问题,但如果您有想法,我很愿意听取。 - KevinF
嗯...你可以用符号链接(symlinks)做些肮脏的事情,这取决于你准备让开发环境与最终构件有多大不同。或者,如果你正在使用一个已拆分的WAR文件,每次修改JSP后单独运行Maven的unpack目标也不会花太长时间。 - artbristol

0
我们在这里使用Subversion,并使用svn:externals(类似符号链接)来共享某些常见代码(主要是.jsp文件)之间的项目。 这种方法相当有效,我们曾经使用OC4J,它实际上有一种方法可以在多个项目之间共享.jsp文件,但由于我们目前正在向Tomcat(或其他东西)迁移,我想出了一种容器无关的方法来做到这一点。

0

Sinuhepop说得没错,但他的答案并不完美。

这里是完美的答案。你需要参考下面的链接,它可以帮助你。

点击这里

在链接页面中,属性内容框的示例不是精确的,你跟着我:

如果需要分享一个文件:

a.jsp  svn://myhome.com/svn/myproject/trunk/a.jsp

如果需要共享文件夹:
xml  svn://myhome.com/svn/myproject/trunk/xml

0

在这种情况下,我更喜欢将所有相关文件(控制器、js、图像等)放在一个jar包中。但问题在于使用JSP文件:如果它们在jar包中,就没有简单的方法来使用它们。但是对于其他视图技术,如VelocityFreemarker,这是一种容易的方式,除了其他优点。我不知道这是否会给您带来太多工作,但对于具有这些需求的新项目而言,这是最佳选择。


有趣...你的意思是说我们可以从/WEB-INF/velocity或JAR中提取Velocity/Freemarker模板?这需要使用Spring MVC自定义ViewResolver来完成吗?我找到的所有示例都只涉及/WEB-INF。 - KevinF
这里有一个很好的例子:http://www.springbyexample.org/examples/velocity-email-template.html - sinuhepop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接