java – How should a spring MVC presentation layer be structured compared to a Symfony2 app?-ThrowExceptions

Exception or error:

To better understand what I’m trying to achieve here is an image of a typical Symfony2 application with only one bundle and a spring MVC app side by side:

enter image description here enter image description here

I know there is a conceptual difference between Symfony2 which can be used to build a whole application and Spring MVC which can also be used to build a whole application, but in my case I want it to act as my presentation layer only.

Working with Spring MVC somewhat feels like working with raw bare metal. I prefer an opinionated approach. I want to have something similar to bundles in Symfony2 where each bundle houses its controllers, views, forms, templates, configurations, js and css. I want views to be grouped by controller name.

I want something that houses the configurations for the whole application such as the database or email server in addition to somewhere where I can add layouts for all “bundles”. I want cache and logs folders.

I know that I can create all of that manually, but I got that feeling that there should be something like a standard folder structure for spring MVC applications.

I almost sound like I searching for a framework built on top of Spring MVC (maybe this is the solution after all), but maybe I’m having the wrong approach to the whole thing.

Note: My business logic is housed in separate bounded contexts. The presentation layer is part of the application that will communicate with all these contexts.

How to solve:

First of all I want to tell that I build a lot of php apps with Symfony (not Symfony 2) so there might be some inconsistency in what I’m telling, but I can share my point of view anyway.

First of all Symfony, as written in php, is complete framework for everything. It has a vision of folder (package) structure not only because it makes your code well organized… but also due to technical limitatins of php. Php is mostly basing on incuding other php sources by using directives like:

include ('/lib/somelib.lib.php');

This is the only way php can load resources. This leads to some consequences in writing frameworks in php. For example in Symfony when you point your browser to http://localhost/some_module/some_url symfony will assume “by convenction” that you want to load a controller named: some_module and you want to execute method some_url in this controller. At the first glance this sounds great, but there is one “catch” in this. Symfony requires it because this is the only way Symfony can infer which controller and which method you want to load (this is probably similar in Symfony2). Otherwise you would need to create extra configuration file.

Java on the other hand gives you many ways to achieve this without forcing you the name of your controller and a method. Spring MVC simply utilizes what java gives you. In Spring you can give any name to your controller, and any name to your method. You can achieve this for example by using annotatations on controller class and method:

@Controller
public class MyController {

  @RequestMapping(value = "/some_module/some_url", method = RequestMethod.GET)
  public ModelAndView searchForSomeData(@PathVariable("currentPage") String currentPageUrlString, @RequestParam("userId") Integer userId) {
  (...)


}

You can place your controller in any folder (package) and spring will discover it via “component scanning feature”. You don’t need to rely on “convention over configuration” which is used in php (because of it’s limitations). You can create some “standard” folder structure but you don’t have to.

Another thing is that Symfony (also due to some limitations how php applications are built) forces you to use its’s own template engine as view technology. That’s why there is what you called “grouping controllers by view name” (you can use other engines for view processing like Smarty but this comes with pain). In Spring on the other hand you are not bound to any view technology. You can use Apache Tiles, jsp pages and whatever you want. You just configure it and use it. What is more you can use two or more view technologies in one application – you only need to tell spring when to use one view technology and when to use the other (for example basing on url prefix). The configuration is surprisingly simple. Simply use annotations, for example like this:

@Configuration
public class WebConfig  {
  @Autowired
  @Qualifier("tilesViewResolver")
  private ViewResolver tilesViewResolver;

  @Autowired
  @Qualifier("jstlViewResolver")
  private ViewResolver jstlViewResolver;

  @Bean
  @DependsOn({ "tilesViewResolver", "jstlViewResolver" })
  public ViewResolver viewResolver() {
    Map<String, ViewResolver> resolvers = new HashMap<>();
    resolvers.put("internal", jstlViewResolver);
    resolvers.put("tilesView", tilesViewResolver);

    ViewResolver globalViewResolver = new PrefixViewResolver(resolvers, jstlViewResolver);
    return globalViewResolver;
  }


  @Bean(name = "tilesViewResolver")
  public ViewResolver tilesViewResolver() {
    UrlBasedViewResolver url = new UrlBasedViewResolver();
    url.setViewClass(TilesView.class);
    return url;
  }


  @Bean(name = "jstlViewResolver")
  public ViewResolver jstlViewResolver() {
    UrlBasedViewResolver resolver = new UrlBasedViewResolver();
    resolver.setPrefix("/WEB-INF/internal/");
    resolver.setViewClass(JstlView.class);
    resolver.setSuffix(".jsp");
    return resolver;
  }
}

So again here Spring does not force you to use anything because it does not operate in environment with some limitations like Symfony in php.

The same goes for logs folder and others. You don’t get the logs folder because you need to declare which technology you want to use for logging in Spring/java (whether it is log4j, logback, commons logging, slf4j etc). In symfony you have your logs folder defined because of two reasons. Firstly you are forced (some people will say “encouraged”, but I prefer to name it “forced”) to use Symfony’s logging system which by default is configured to use “logs” directory in your application directory. Secondly again the limitations/characteristics of php comes – when you deploy php application you usually keep the logs in application folder because you don’t have permission to write to any other folder on filesystem. When you deploy java application on Tomcat you usually keep the logs in Tomcat directory or other directory on filesystem.

So the bottom line is freedom. That’s why you don’t get any “standard” in Spring MVC in this area. You create your own standard which fits your application.

Leave a Reply

Your email address will not be published. Required fields are marked *