Getting Started with Scalate: Simple Web Application with Spring MVC
What’s Scalate ?
Scalate (Scala Template Engine) is a kind of template engine which uses scala programming language. And useful if you want to use java and scala together in a web application.
Scalate supports 4 different template languages. These are ssp, scaml, jade, mustache. But we will use ssp to build our presentation layer. We can define ssp like jsp. Only differences each other is scala actually. But I think its a big advantage. Because scala has good performance in jvm, and it affects scalate template engine’s performance.
So, lets start to add scalate library to our maven pom.xml file.
<dependency> <groupId>org.fusesource.scalate</groupId> <artifactId>scalate-spring-mvc_2.10</artifactId> <version>1.6.1</version> </dependency>
This is our config class for scalate, it uses spring framework configuration annotion to show this java class as an config class. DEFAUL_PREFIX is our path for .ssp files. Scalate will scan that path to find ssp file. We are using DEFAULT_SUFFIX to show scalate template engine our files extensions scalate should see. And DEFAULT_LAYOUT will be available for all .ssp files. We can us it for static thing like header, footer, or something like that.
@Configuration public class ScalateConfig { public static final String DEFAULT_PREFIX = "/WEB-INF/templates/"; public static final String DEFAULT_SUFFIX = ".ssp"; public static final String DEFAULT_LAYOUT = "/WEB-INF/templates/layouts/default.ssp"; @Configuration protected static class ScalateConfigConfiguration implements ServletContextAware { private ServletContext servletContext; @Override public void setServletContext(ServletContext servletContext) { this.servletContext = servletContext; } @Bean public Config config() { return new Config() { @Override public ServletContext getServletContext() { return servletContext; } @Override public String getName() { return "unknown"; } @Override public Enumeration<?> getInitParameterNames() { return null; } @Override public String getInitParameter(String name) { return null; } }; } } @Configuration protected static class ScalateServletTemplateEngineConfiguration { @Autowired private Config config; @Bean public ServletTemplateEngine servletTemplateEngine() { ServletTemplateEngine engine = new ServletTemplateEngine(config); engine.layoutStrategy_$eq(getLayoutStrategy(engine)); return engine; } private LayoutStrategy getLayoutStrategy(ServletTemplateEngine engine) { List<String> layouts = new ArrayList<String>(1); layouts.add(DEFAULT_LAYOUT); return new DefaultLayoutStrategy(engine, JavaConversions.asScalaBuffer(layouts)); } } @Configuration protected static class ScalateViewResolverConfiguration { @Autowired private ServletTemplateEngine servletTemplateEngine; @Bean public ScalateViewResolver scalateViewResolver() { ScalateViewResolver resolver = new ScalateViewResolver(); resolver.templateEngine_$eq(servletTemplateEngine); resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 20); resolver.setPrefix(DEFAULT_PREFIX); resolver.setSuffix(DEFAULT_SUFFIX); return resolver; } } }
We will use spring boot for our scalate web application.
@Configuration @EnableAutoConfiguration @ComponentScan("com.furkanzumrut") public class Application extends SpringBootServletInitializer { public static void main(String... args) { SpringApplication.run(Application.class, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } }
We defined a simple product pojo class for our products.
import java.math.BigDecimal; public class Product { private Long productId; private String productName; private BigDecimal productPrice; public Product(Long productId, String productName, BigDecimal productPrice) { this.productId = productId; this.productName = productName; this.productPrice = productPrice; } public Long getProductId() { return productId; } public void setProductId(Long productId) { this.productId = productId; } public String getProductName() { return productName; } public void setProductName(String productName) { this.productName = productName; } public BigDecimal getProductPrice() { return productPrice; } public void setProductPrice(BigDecimal productPrice) { this.productPrice = productPrice; } }
We have simple product list controller created with spring mvc and it gives us products list object when we request products path.
@Controller @RequestMapping("/products") public class ProductListController { @RequestMapping(method = RequestMethod.GET) public ModelAndView getProducts() { ModelAndView mav = new ModelAndView("layout:home/productList"); List<Product> products = new ArrayList<Product>(); products(new Product(1L,"Iphone 6", BigDecimal.valueOf(2444.44)); products(new Product(2L,"Iphone 5", BigDecimal.valueOf(1444.44)); mav.addObject("products",products); return mav; } }
This is our default.ssp file, and its available for our all ssp file. As you see, body, title will be dynamic parts in our web application.
<%@ var body: String %> <%@ var title: String = "Simple Product Management System" %> <!DOCTYPE html> <html lang="en"> <head> <title>${title}</title> </head> <body> ${unescape(body)} </body> </html>
This is our productList.ssp file. We can use any scala code in our ssp file as we wish.
<% attributes("title") = "Product List - Simple Product Management System" %> <% import com.furkanzumrut.domain.Product %> <% import java.util %> <%@ val products : java.util.List[Product] %> <div class="modal-header"> <h3>Product List</h3> </div> <div> <table> <thead> <tr> <th>Product Id</th> <th>Product Name</th> <th>Product Price</th> </tr> </thead> <tbody> #for (product <- products) <tr> <td>${product.getId}</td> <td>${product.getName}</td> <td>${product.getPrice}</td> </tr> #end </tbody> </table> </div>
Also, you can check http://scalate.github.io/scalate/documentation/index.html to learn something new about scalate. And you can check my simple project on github to understand scalate basically.
https://github.com/furkanzumrut/product-management-system