Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Scala Spring 4 MVC without Web.XML configuration with static resources handling

DZone's Guide to

Scala Spring 4 MVC without Web.XML configuration with static resources handling

· Performance Zone
Free Resource

Evolve your approach to Application Performance Monitoring by adopting five best practices that are outlined and explored in this e-book, brought to you in partnership with BMC.

This blog post is fully focused on Scala and how to use it for Spring 4 based JavaEE application development. I'll  modify the example application I've used in my blog posts previously published on my personal blog  ("Spring4Netty without Web.XML configuration on Java 8.. ").    

Spring Framework is so popular in Java-land, but using Scala can give it wings and shift it to a new level of developer experience. 

In the example application I've used the popular AngularJS Framework for the front-end.  My personal experiences of using AngularJS for event-driven application with Scala is really positive. I find it much "easier" (still a lot of work :) and comfortable to understand back-end and front-end functionality. 

To build a new Spring 4 Scala example application I used the following tools:

  • SBT % 0.13.0
  • Spring4 % 4.0.6.RELEASE
  • Scala % 2.10.3
  • Jetty % 9.1.0
  • Jetty server can be easily replaced by Tomcat 7.

    The whole sample application has been developed in IntelliJ IDEA 13.x IDE. 

    After we have created the SBT project under IntelliJ we need to import some plugins.


    To import them we change the sbt plugin setup by modifying file in following manner. 

    addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "1.0.0-M4")
    
    addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.6.0")

    We have now added two plugins:  xsbt-web-plugin and sbt-idea. The xsbt-web-plugin is used for building web enterprise applications. Both of them are extensions to the SBT building tool.

    The next step is to add necessary libraries dependences into the build.sbt file. As we also want to link static resources for front-end development, the number of needed libraries will be bigger. 

    The build.sbt file will look after our modification in the following example.

    name := "miko-spring-scala"
    
    version := "1.0"
    
    scalaVersion := "2.11.2"
    
    libraryDependencies ++= Seq(
      "org.springframework" % "spring-webmvc" % "4.0.6.RELEASE",
      "org.springframework" % "spring-context" % "4.0.6.RELEASE",
      "org.springframework" % "spring-context-support" % "4.0.6.RELEASE",
      "javax.servlet" % "javax.servlet-api" % "3.0.1" % "provided",
      "javax.servlet" % "jstl" % "1.2" % "compile",
      "org.eclipse.jetty" % "jetty-webapp" % "9.1.0.v20131115" % "container, compile",
      "org.eclipse.jetty" % "jetty-jsp" % "9.1.0.v20131115" % "container"
    )
    jetty(port = 9090) 

    When the SBT application is ready we will use commands to start/stop it.

    //SBT console ...
    container:start
    container:stop
    //END SBT console

    All libraries and plugins are ready and we can start building Spring4 Scala Application without using Web.XML and with linked static resources for next front-end development. Web.xml file will look almost empty in contracts to XML configuration.

    The application package structure is very similar to the previous ones. I want to keep consistency and gain the possibility to have references to the Java implementation in case of possible comparison.

     


    Now I simply turn the Java into the Scala in several steps
    1. Scala WebConfig will look like this:

    @Configuration
    @ComponentScan(basePackages = Array("miko.scala.helloexample"))
    @EnableWebMvc
    class WebConfig extends WebMvcConfigurerAdapter{
    
      override def addResourceHandlers(registry: ResourceHandlerRegistry) = {
        registry.addResourceHandler("/app/**").addResourceLocations("/app/").setCachePeriod(31550522)
      }
    
      override def configureDefaultServletHandling(configurer: DefaultServletHandlerConfigurer) = {
        configurer.enable()
      }
    
      @Bean
      def viewResolver = {
        val viewResolver = new InternalResourceViewResolver
        viewResolver.setViewClass(classOf[JstlView])
        viewResolver.setPrefix("/WEB-INF/pages/")
        viewResolver.setSuffix(".jsp")
        viewResolver
      }
    }

    2. Scala WebInitializer will help us set up ServletContext at start up.

    class WebInitializer extends WebApplicationInitializer{
    
      override def onStartup(servletContext: ServletContext) = {
        val ctx = new AnnotationConfigWebApplicationContext
        ctx.register(classOf[WebConfig])
    
        ctx.setConfigLocation("META-INF/spring/app-spring-scala.xml")
    
        val servlet: Dynamic = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx))
        servlet.addMapping("/")
        servlet.setLoadOnStartup(1)
      }
    }

    3. Scala HelloExampleController class annotated by @Contoller. The Annotation takes care of HttpServletRequest and Responses. This example controller also shows how Services are @Autowired when Scala language is used.

    @Controller
    @RequestMapping(Array("/"))
    class HelloExampleController @Autowired() (exampleService: ExampleService, exampleImportService: ExampleImportService){
    
      @RequestMapping(method =  Array(RequestMethod.GET))
      def hello( model: Model) = {
        model.addAttribute("message", "Here is Scala with ServiceName = " + exampleService.serviceName)
        model.addAttribute("importMessage", "Here is Scala with ServiceImportName = " + exampleImportService.name)
        "hello"
      }
    }

    4. Scala Example...Services used by HelloExampleController are done over the quite powerful Traits implementation. Traits are very similar to Java Interfaces but they allow partial implementation which makes them much more powerful (out of blog post scope ;). 

    trait ExampleImportService {
      def name: String
    }
    -----
    class ExampleImportServiceImpl extends ExampleImportService{
      override def name: String = "Imported service over XML"
    }
    Aafter all those steps we have a Scala Spring 4 application to test. Additionally we also have source code to compare with previous Java 8 implementation.

    Scala does great work, because thinking in functions and callback intentions makes whole development more straightforward. 
    Enjoy sample application ! 


    Learn tips and best practices for optimizing your capacity management strategy with the Market Guide for Capacity Management, brought to you in partnership with BMC.

    Topics:

    Published at DZone with permission of Miro Wengner. See the original article here.

    Opinions expressed by DZone contributors are their own.

    The best of DZone straight to your inbox.

    SEE AN EXAMPLE
    Please provide a valid email address.

    Thanks for subscribing!

    Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
    Subscribe

    {{ parent.title || parent.header.title}}

    {{ parent.tldr }}

    {{ parent.urlSource.name }}