Best practices for sharing web-tier code (Controll

2020-05-24 06:27发布

问题:

I'm working on rewriting some aging web applications. There are two in particular that are very, very similar, yet share no code today and I aim to fix that.

The projects are being rewritten with Maven, Spring MVC, and Sitemesh.

Model tier code is easy enough to share using JARs. But I don't know of any good ways to share common web-tier code (JSPs and Controllers) between similar apps.

Here's some background. These apps are webstores. One is a normal store (think amazon.com) that a user can sign into, search products, add to a shopping cart, and check out. The other is basically the same thing, only it's a punchout site. The product browse and shopping cart portions are identical. Sign in and checkout, however, are completely different.

I'm oversimplifying, but it's enough to illustrate the problem. There's a significant portion of web-tier code in the product browse and shopping cart sections that should be able to be shared between the two.

I don't think it's possible to simply have the same WAR file running as either "mode" based on an environment variable or settings from a different database. One of the differences is a completely different Spring Security config. It would also be preferable to leave the other site's sign-in and checkout controllers out of the component-scan so nobody can somehow cross over to the wrong one with URL manipulation.

I originally started using Maven Profiles and filtering to keep two different config sets (web.xml, spring configs, etc.) in the same WAR project. Based on which Maven profile is selected, the resulting WAR is built with a different config set (and a different name for clarity). This violates the Maven principal that one pom produces one artifact.

Is there a better way to do this? What about Maven WAR Overlays? I see people talking about using overlays to share common resources like CSS, JS, images, and even some common JSPs. But I don't see anyone mention sharing classes like Controllers this way.

I could push the Controller classes down to the JARs, but logically it seems they should stay with their respective JSPs. And JSPs can't also be pushed down to the JARs (right?).

I also thought about making it an EAR containing multiple WAR files -- one WAR for the common shopping experience, and another WAR for the appropriate sign-in and checkout. I believe the session can be shared between two WARs in the same EAR, but I'm not sure if it plays nice with Spring's session-scope beans. I hear they're not really stored in the session. I'd also have to figure out what to do about the Sitemesh decorators being used for the header/footer. The same Sitemesh config and its resources would need to be copied into both WARs, right? So in the end, the shopping WAR artifact would still be different in each circumstance.

I have to believe that other people have dealt with this before. Am I thinking about it the wrong way? Is there a common solution for this sort of thing?

回答1:

Good work doing battle against copy-paste. Why do you say it's hard to share JSPs? You can copy them out of a shared jar using the maven dependency plugin:

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


回答2:

My preferred option in this cases is put all related files (controllers, js, images...) in a jar. But the problem here is the use of JSP files: there is no easy way of using them if they are in a jar. But with other view technologies such as Velocity or Freemarker this is possible in an easy way, among other advantages. I don't know if this can lead you to too much work, but for a new project with these needs it is the best option.



回答3:

We are using Subversion here, and use svn:externals (kind of like symbolic links) in order to share certain common code (mostly .jsp files) between projects. Works fairly well, we were using OC4J which actually has a way to share .jsp's between multiple projects, but since we are currently moving towards Tomcat (or something else) I wanted to come up with a container agnostic way to do it.



回答4:

Sinuhepop is right ,but his answer not perfect.

Here is the perfect answer. you have to refer the follow url, it can hep you.

click here

in the url page, the example for the property content box is not exact, you follow me:

if need to share a file:

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

if need to share a folder:

xml  svn://myhome.com/svn/myproject/trunk/xml