My Works

Scala Based SpringMVC Application Without XML

Here we are going to look at creating a simple example in Scala language for SpringMvC with WebApplicationIntializer. It means that we would not be requiring web.xml as means of initialising the servlet.Therefore we would not have web.xml in our example. We would be programmatically configuring without using the xml files and use annotation based loading of context and beans.

  1. Project Dependencies.
  2. Create WebInitializer.
  3. Create MVC Context Configuration programmatically.
  4. Create View Configuration programmatically.
  5. Create helloworld example JSP page.
  6. Add a unit test for the controller.
  7. Based on the Unit test create the controller.
  8. Deploy and Run.

1.Project Dependencies.

JDK 1.6 or above,In this case have chosen Tomcat 7.0.67 , Spring MVC jars, Scala 2.11.7 is used in this Example, junit jar and logging jars are the ones we would need. The build.gradle file dependencies are listed below.

	
apply plugin: "scala"
apply plugin: "eclipse"
apply plugin: "war"
apply plugin: "eclipse-wtp"
apply plugin: "com.bmuschko.tomcat"
group = projGroup
version = projVersion
buildscript {
repositories {
jcenter()
maven { url 'https://plugins.gradle.org/m2/' }
}

dependencies {
classpath "com.bmuschko:gradle-tomcat-plugin:2.2.4"
}

}
repositories {
mavenCentral()
maven { url 'http://scala-tools.org/repo-releases' }
maven { url 'http://scala-tools.org/repo-snapshots' }
maven { url 'http://repository.springsource.com/maven/bundles/release' }
maven { url 'http://repository.springsource.com/maven/bundles/external' }

}
war {
archiveName 'SpringMVCScalaWebIntializer.war'
}
dependencies {
compile "org.scala-lang:scala-library:2.11.7"
providedCompile ("javax.servlet:javax.servlet-api:3.0.1")
compile ("org.springframework:spring-webmvc:3.2.3.RELEASE")
compile ("org.springframework:spring-expression:3.2.3.RELEASE")
compile ("org.springframework:spring-test:3.2.3.RELEASE")
compile ("commons-logging:commons-logging:1.1.1")
compile ("org.slf4j:jcl-over-slf4j:1.7.0")
compile ("org.slf4j:slf4j-api:1.7.0")
compile ("org.slf4j:slf4j-log4j12:1.7.0")
compile ("junit:junit:4.11")
}
sourceSets {
main {
scala {
include '**/*.scala'
}
}
}
sourceSets {
test {
scala {
include '**/*.scala'
}
}
}
dependencies {
def tomcatVersion = '7.0.67'
tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}",
"org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}",
"org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}"
}
task wrapper(type: Wrapper) { gradleVersion = '2.10' }
	
	

gradle.properties



projGroup=org.srinivas.siteworks
projName=SpringMVCScalaWebIntializer
projVersion=1.0-SNAPSHOT


settings.gradle



rootProject.name = projName


2.Create WebInitializer.

SpringMVC with Servlet 3.0 detects the WebApplicationInitializer implementations by using SpringServletContainerInitializer. Thus help to initialize our web application by configuring the ServletContext programmatically.So We create a class SrinivasExampleWebApplicationInitializer which implements the WebApplicationInitializer. This class methods starts up the web application with a Servlet registered with required contexts and beans. In This class a DispatcherServlet is created containing programmatically configured AnnotationConfigWebApplicationContext.The dispatcher is also mapped to .html. For more info on WebApplicationInitializer, Please refer here..

		

class SrinivasExampleWebApplicationInitializer extends WebApplicationInitializer {
val logger = LoggerFactory.getLogger(classOf[SrinivasExampleWebApplicationInitializer])
/* (non-Javadoc)
* @see org.springframework.web.WebApplicationInitializer#onStartup(javax.servlet.ServletContext)
*/

override def onStartup(container:ServletContext):Unit = {
logger.info("Started to pickup the annotated classes")
startServlet(container);
}
/**
* Start servlet.
*
* @param container   the ServletContext
*/
private def startServlet(container:ServletContext):Unit = {
val dispatcherContext:WebApplicationContext = registerContext(classOf[MvcContextConfiguration])
val  dispatcherServlet:DispatcherServlet = new DispatcherServlet(dispatcherContext)
val dispatcher:ServletRegistration.Dynamic = container.addServlet("dispatcher",dispatcherServlet)
dispatcher.setLoadOnStartup(1)
val mapping: String = "/"
dispatcher.addMapping(mapping);
}
/**
* Register context.
*
* @param annotatedClasses the Class type variable argument of classes that needs to be registered to the context.
* @return the web application context
*/
def registerContext(@varargs annotatedClasses:Class[_]):WebApplicationContext = {
logger.info("Using AnnotationConfigWebApplicationContext createContext");
val context:AnnotationConfigWebApplicationContext  = new AnnotationConfigWebApplicationContext()
context.register(annotatedClasses)
return context;
}

}
	
	

3.Create MVC Context Configuration programmatically.

Now, We are going to configure the MVC context programmatically. This is achieved by creating a class MvcContextConfiguration which extends the Abstract WebMvcConfigurerAdapter.Usually MvcContextConfiguration class can contain method for registering interceptors for security purposes, can contain method to register view controllers and so on.We in this case override the method configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) by enabling DefaultServletHandlerConfigurer.This means unhandled requests are delegated by forwarding to the Servlet container's "default" servlet. This method is optional and is not required in our example.However it is included to explain the purpose achieved by overriding the methods of WebMvcConfigurerAdapter. MvcContextConfiguration class enables WebMVC based on annotation and scans the base packages for the annotated resources. These are further registered by the web application context of the default servlet which was initialized by WebApplicationInitializer. For more info on WebMvcConfigurerAdapter, Please refer here..

		

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = Array("org.srinivas.siteworks","org.srinivas.siteworks.controllers"))
class MvcContextConfiguration extends WebMvcConfigurerAdapter {
val logger = LoggerFactory.getLogger(classOf[MvcContextConfiguration])

override	def configureDefaultServletHandling(configurer:DefaultServletHandlerConfigurer ):Unit={
logger.info("WebMvcContextConfiguration: configureDefaultServletHandling Method")
configurer.enable();
}
}
	
	

4.Create View Configuration programmatically.

We now create a class ViewConfiguration.This class beans are loaded during the component scan of class MvcContextConfiguration. Thereby it is registered to the servlet. We programmatically configure a ViewResolver bean of Type InternalResourceViewResolver in this class. This helps the view class to be preconfigured with the set prefix and set suffix.

		
	
/**
* View resolver.
*
* @return the Resolved view
*/
@Bean
def viewResolver():ViewResolver = {
logger.info("ViewConfiguration viewResolver()")
val viewResolver:InternalResourceViewResolver = new InternalResourceViewResolver()
viewResolver.setOrder(1)
viewResolver.setPrefix("/WEB-INF/displays/")
viewResolver.setSuffix(".jsp")
return viewResolver
}
}

	
	

5.Create helloworld example JSP page.

Now, we need to create a simple jsp page which takes the model attribute message which was set in the Controller.

		
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>My Works:WebApplicationInitializer</title>
</head>
<body>
 <p>${message}</p>
</body>
</html>
	
	

6.Add a unit test for your controller.

Now, we need to add unit test for the controller of helloworld.jsp that we created. In this case we are executing the unit test using SpringJUnit4ClassRunner. We are actually checking the HelloWorldController for successful status, return of view string and for the message attribute. For more info on MockMvC, Please refer here..

		
	
@RunWith(classOf[SpringJUnit4ClassRunner])
@ContextConfiguration(classes = Array(classOf[HelloWorldControllerTestConfiguration]))
class HelloWorldControllerTest {
val logger = LoggerFactory.getLogger(classOf[HelloWorldControllerTest])

@Autowired val helloWorldController:HelloWorldController = null
/**
* Test helloPage method of HelloWorldController
*/
@Test
def  testHelloPage():Unit = {
val  mockMvc:MockMvc = MockMvcBuilders.standaloneSetup(this.helloWorldController).build()
try {
mockMvc.perform(MockMvcRequestBuilders.get("/helloworld.mvc"))
.andExpect(status().isOk())
.andExpect(view().name("helloworld"))
.andExpect(forwardedUrl("helloworld"))
.andExpect(handler().methodName("helloPage"))
.andExpect(
model().attribute(
"message",
helloWorldController.STRING_MESSAGE_WELCOME_TO_WEB_APPLICATION_INITIALISER));
} catch {
case e: Exception => {
logger.info("Error",e);
fail("Failed Due to: "+e.getMessage());		}
}
}
}
	
	

7.Based on the Unit test create the controller.

Based on the expected results in the Unit test for helloworld.jsp controller that we created above.We now create the HelloWorldController.

		

@Controller
class HelloWorldController {
val STRING_MESSAGE_WELCOME_TO_WEB_APPLICATION_INITIALISER:String = "Welcome to WebApplication Initialiser"
val logger = LoggerFactory.getLogger(classOf[HelloWorldController])

/**
* Hello page.
*
* @param model the model
* @return the string
*/
@RequestMapping(value = Array("/helloworld.mvc"), method =Array(RequestMethod.GET))
def helloPage(model:Model):String = {
logger.info("HelloWorldController")
model.addAttribute("message",STRING_MESSAGE_WELCOME_TO_WEB_APPLICATION_INITIALISER)
return "helloworld";
}
}
	
	

8.Deploy and Run.

Build the project and deploy SpringMVCScalaWebIntializer.war from build/libs folder on to the chosen Tomcat 7.0.67. For Gradle building of the project you can refer to ReadMe.txt instructions in the worked out example.You can download the Worked example and Follow the commands provided in the zip to run embedded Tomcat. Following deployment to Tomcat(emmbedded or standalone) and starting the Tomcat(Standalone),the localhost result is as below.

Calling Hello World on Web ApplicationIntializer