SlideShare a Scribd company logo
1 of 45
Download to read offline
Scala Italy 25 may 2013
Scalatra comparison with SpringMVC
Massimiliano Dessì
1
Monday, May 27, 13
GDG Sardegna
Speaker
Max has more than 13 years of experience in programming. He’s a
proud father of three.
Manager of GTUG Sardegna, Founder of SpringFramework IT,
co-founder of Jug Sardegna.
Author of Spring 2.5 AOP.
He works in Energeya as a Product Architect and lives in Cagliari,
Italy.
2
Monday, May 27, 13
GDG Sardegna
Scalatra - SpringMVC
CRUD HTML
REST
JSON
Routing
Template
Security
Agenda
3
Monday, May 27, 13
GDG Sardegna
Spring , Since 2004 - Java Full Stack - Lot of people involved
now property of VMware
Scalatra , Since 2009 - Scala Http Microframework (DSL)
the BBC, LinkedIn,
the Guardian,
games website IGN,
UK government
rely on Scalatra.
Some info
4
Monday, May 27, 13
GDG Sardegna
REST
class JellyBeans extends ScalatraServlet {
get("/jellybs/:id") { ... }
post("/jellybs") { ... }
put("/jellybs/:id") { ... }
delete("/jellybs/:id") { ... }
}
For browser add PUT & DELETE support client side
X-HTTP-METHOD-OVERRIDE or _method=put _method=delete in the post body
class JellyBeansBrowser extends ScalatraFilter with MethodOverride
5
Monday, May 27, 13
GDG SardegnaMassimiliano Dessì
Routes
class JellyBeans extends ScalatraServlet {
get("/jellybs/:id") {
val id:Int = params.getOrElse("id", halt(400)).toInt
...
}
get("/jellybs/download/*.*") { //with wildcard
...
}
get("""^/j(.*)/f(.*)""".or) { //REGEX
...
}
post("/jellybs", request.getRemoteHost == "127.0.0.1",
request.getRemoteUser == "admin") {
....
}
6
Monday, May 27, 13
GDG Sardegna
REST
@Controller
public class JellyBeansController{
@RequestMapping(value = "/jellybs/{id}", method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK) //Http 200
public @ResponseBody JellyB getItem(@PathVariable("id") Integer id) {...}
@RequestMapping(value = "/jellybs", method = RequestMethod.POST) //Http 201
@ResponseStatus(HttpStatus.CREATED) //Http 201
public void createJelly(HttpServletRequest req, HttpServletResponse res,
@RequestBody JellyB item) { ... }
@RequestMapping(value = "/jellybs/{id}", method = RequestMethod.PUT)
@ResponseStatus(HttpStatus.NO_CONTENT) //Http 204
public void updateItem(@RequestBody JellyB item, @PathVariable("id") Integer id)
{ ... }
@RequestMapping(value = "/items/{id}", method = RequestMethod.DELETE)
@ResponseStatus(HttpStatus.NO_CONTENT)//204
public void deleteItem(@PathVariable("id") String id) { ... }
}
For browser add PUT & DELETE support client side
X-HTTP-METHOD-OVERRIDE or _method=put _method=delete in the post body
<filter>
<filter-name>hiddenMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
7
Monday, May 27, 13
GDG Sardegna
Routes
class JellyBeans extends ScalatraServlet {
get("/jellybs/:id") {
val id:Int = params.getOrElse("id", halt(400)).toInt
...
}
get("/jellybs/download/*.*") { //with wildcard
...
}
get("""^/j(.*)/f(.*)""".or) { //REGEX
...
}
post("/jellybs", request.getRemoteHost == "127.0.0.1",
request.getRemoteUser == "admin") {
....
}
8
Monday, May 27, 13
GDG Sardegna
HandlerMapping
@Controller
public class JellyBeansController{
@RequestMapping(value="/jelly.pdf",method = RequestMethod.GET)
public ModelAndView pdf(HttpServletRequest req,@RequestParam String id)
{
...
}
@RequestMapping(value = "/jellybs/{id}", method = RequestMethod.GET)
public String getItem(@PathVariable("id") Integer id) {
...
}
@RequestMapping(value = "/jellybs", method = RequestMethod.POST)
public void createJelly(@ModelAttribute(”jelly”) JellyB jelly) {
...
}
}
DefaultAnnotationHandlerMapping
SimpleUrlHandlerMapping
ControllerClassNameHandlerMapping
9
Monday, May 27, 13
GDG Sardegna
Filter
class JellyBeans extends ScalatraServlet {
before() {
db.acquireConnecion
contentType="text/html"
}
get("/") {
val menu = db.findWelcome()
templateEngine.layout("index.ssp", menu)
}
after() {
db.releaseConnection
}
}
Like Servlet Filter
(or Aspect Oriented Programming)
You can add logic before or the
routes
10
Monday, May 27, 13
GDG Sardegna
Handler Interceptor
public interface HandlerInterceptor{
//before call method’s controller
boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler)
throws Exception;
//after call method’s controller
void postHandle(HttpServletRequest req, HttpServletResponse res, Object handler,
ModelAndView mav) throws Exception;
//after view render()
void afterCompletition(HttpServletRequest req, HttpServletResponse res, Object
handler, Exception ex) throws Exception;
}
Handler mapped on all controllers (as a property of Handlermapping config)
or mapped on url path with <mvc:interceptors> tags
Like Servlet Filter
(or Aspect Oriented Programming)
You can add logic before or after
the controllers methods
11
Monday, May 27, 13
GDG Sardegna
Handlers
Handlers are top level methods for http routines
class JellyBeans extends ScalatraServlet {
notFound {
<h1>Not found</h1>
}
halt(status = 301, headers =
Map("Location" -> "http://www.codemotion.com/"))
get("/jellybs/names/*") {
"Name not found!"
}
}
12
Monday, May 27, 13
GDG Sardegna
Handlers
class JellyBeans extends ScalatraServlet {
get("/jellybs/names/:who") {
params("who") match {
case "Cherry" => "Found Cherry!"
case _ => pass() /* call the next matching route route, routes are
matched from bottom up*/
}
}
get("/jellybs/download/:id") {
jellyBeanService.find(params("id")) match {
case Some(jellybean) => Ok(jellybean)
case None => NotFound("Sorry, jellybean not found")
}
}
}
13
Monday, May 27, 13
GDG Sardegna
Request Response & Friends
class JellyBeans extends ScalatraServlet {
get("/jellybs/shows/:id") {
//access to request,response, session and params
request.body //request body as a string
request.cookies // cookie map
request.isAjax // is ajaxRequest
request.getSession // HttpServletSession
request.locale // user locale
response.getOutputStream //response outputstream
servletContext.get("myIntParam") //servlet context
val idString = params("id")
val id = params.getAs[Int]("id")
//val id = params.getOrElse("id", halt(500)) //another way
....
}
}
14
Monday, May 27, 13
GDG Sardegna
Request Response & Friends
class JellyBeans extends ScalatraServlet {
get("/jellybs/*/conf/*") {
// Matches "GET /jellybs/one/conf/two"
multiParams("splat") // Seq("one", "two")
//wildcard accessible with key splat
}
get("""^/jelly(.*)/fla(.*)""".r) {
// Matches "GET /jellybs/flavor"
multiParams("captures") // == Seq("bs", "vor")
}
}
15
Monday, May 27, 13
GDG Sardegna
Gzip
class GzipJellyBeans extends ScalatraServlet with GZipSupport{
get("/") {
<html>
<body>
<h1>This is
<a href="http://en.wikipedia.org/wiki/Sparta">Sparta</a>!
</h1>
</body>
</html>
}
}
16
Monday, May 27, 13
GDG Sardegna
Flash message
class FlashServlet extends ScalatraServlet with FlashMapSupport{
post("/jellybs/create") {
flash("notice") = "jellybean created successfully"
redirect("/home") //redirect
}
get("/home") {
ssp("/home") //Scala Server Pages
}
17
Monday, May 27, 13
GDG Sardegna
ExceptionResolvers
<bean id="exceptionResolver"
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="org.springframework.web.HttpSessionRequiredException">welcome</prop>
...
</props>
</property>
</bean>
or in a annotated @Controller class
@ExceptionHandler
public String requestParamNotPresent(HttpMediaTypeException ex)
18
Monday, May 27, 13
GDG Sardegna
Binding
To avoid manual binding from http and our Object Scalatra provide a binding module
case class MyClass(id: Integer, name: String)
post("/myroute") {
val cmd = command[CreateMyClassCommand]
...
}
19
Monday, May 27, 13
GDG Sardegna
Binding
Under the hood
abstract class MyClassCommand[S](implicit mf: Manifest[S])
extends ModelCommand[S] with JsonCommand {
  
implicit def todoStringValidators(b: FieldDescriptor[String]) =
new MyClassStringValidations(b)
}
class CreateMyClassCommand extends MyClassCommand[MyClass] {
protected implicit val jsonFormats = DefaultFormats
val name: Field[String] = asType[String]("name").notBlank.minLength(3)
}
20
Monday, May 27, 13
GDG Sardegna
Binding
Under the hood
class MyClassStringValidations(b: FieldDescriptor[String]) {
def startsWithCap(message: String = "%s must start with a capital letter.") =
b.validateWith(_ =>
     _ flatMap {
new PredicateValidator[String](
b.name,
"""^[A-Z,0-9]""".r.findFirstIn(_).isDefined,
message).validate(_)
   )
}
)
}
21
Monday, May 27, 13
GDG Sardegna
CommandObject
@RequestMapping(value = "/items/{id}", method = RequestMethod.PUT)
@ResponseStatus(HttpStatus.NO_CONTENT)
public String updateItem(JellyB item) {
...
}
Spring bind the request body on the object used in the method (JellyB)
Objects Validation with jsr 303 annotation or with Validator Spring Interface
Error message with JSP/JSTL tags
22
Monday, May 27, 13
GDG Sardegna
Upload
import org.scalatra.ScalatraServlet
import org.scalatra.servlet.FileUploadSupport
import javax.servlet.annotation.MultipartConfig
@MultipartConfig(maxFileSize=10*1024)
trait StorageRoutes extends FileUploadSupport {
self: ScalatraServlet =>
}
23
Monday, May 27, 13
GDG Sardegna
JSON
Automatic Serialization and deserialization of any Case class
object JSONServlet extends ScalatraServlet with JacksonJsonSupport{
case class JellyBean(id: Int, name: String, flavor:String)
protected implicit val jsonFormats: Formats = DefaultFormats
before() {
contentType = formats("json")
}
....
24
Monday, May 27, 13
GDG Sardegna
Actors
The routes can returns a Future
class MyActorServlet(system:ActorSystem, myActor:ActorRef)
extends ScalatraServlet with FutureSupport {
import _root_.akka.pattern.ask
implicit val timeout = Timeout(10)
protected implicit def executor: ExecutionContext = system.dispatcher
get("/async") {
myActor ? "Do stuff and give me an answer"
}
get("/fire-forget") {
myActor ! "Hey, you know what?"
Accepted() //if you do not want return a future
}
}
25
Monday, May 27, 13
GDG Sardegna
Actors
get("/async") {
myActor ? "Do stuff and give me an answer"
}
get("/fire-forget") {
myActor ! "Hey, you know what?"
Accepted() //if you don’t want return a future
}
class CodemotionActor extends Actor {
def receive = {
case "Do stuff and give me an answer" => sender ! "The answer is 42"
case "Hey, you know what?" => println("Yeah I know...")
}
}
}
26
Monday, May 27, 13
GDG Sardegna
Akka
Akka start in the Bootstrap of Scalatra
class ScalatraBootstrap extends LifeCycle {
val system = ActorSystem()
val codemotionActor = system.actorOf(Props[CodemotionActor])
override def init(context: ServletContext) {
context.mount(new JSONServlet, "/jellybs/*")
context.mount(new FrontServlet, "/template/*")
context.mount(new MyActorServlet(system, codemotionActor), "/actors/*")
}
override def destroy(context:ServletContext) {
system.shutdown()
}
}
27
Monday, May 27, 13
GDG Sardegna
Deployment
Scalatra is based on regular Java Servlet 3.0
it can start from:
Standalone from jetty embedded
From Servlet container
Heroku
Jelastic
CloudBees
GAE (not out of the box )
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<listener>
<listener-class>org.scalatra.servlet.ScalatraListener</listener-class>
</listener>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/img/*</url-pattern>
<url-pattern>/css/*</url-pattern>
<url-pattern>/js/*</url-pattern>
<url-pattern>/assets/*</url-pattern>
</servlet-mapping>
</web-app>
28
Monday, May 27, 13
GDG Sardegna
JSON
Automatic Serialization and deserialization of any Case class
object JSONServlet extends ScalatraServlet with JacksonJsonSupport{
...
get("/jellybs/all"){
jellyBeanRepo.all //from class to json
}
post("/jellybs/create") {
val jb = parsedBody.extract[JellyBean] //from json to class
...
}
}
29
Monday, May 27, 13
GDG Sardegna
JSON
30
JSON with third party lib es Jackson
@JsonCreator
public JellyB(Map map) {...}
@JsonAnyGetter
public Map toMap() {...}
Automatic binding
public @ResponseBody JellyB getItem(...)
public void updateItem(@RequestBody JellyB item)
Monday, May 27, 13
GDG Sardegna
Template
Html inline,
Scalate
Twirl (Play2 template)
Scalate
mean
SSP (Scala Server Page)
Scaml
Mustache
Jade
31
Monday, May 27, 13
GDG Sardegna
Template
class ScalateServlet extends ScalatraServlet with ScalateSupport{
get("/"jellybeans/ssp) {
contentType="text/html"
ssp("/index", "foo" -> "uno", "bar" -> "two")
// the layout used it’s WEB-INF/layouts/default.ssp
}
get("/jellybeans/jade") {
jade("/index", "layout" -> "", "foo" -> "one", "bar" -> "two")
// render without a layout.
}
get("/jellybeans/direct") {
templateEngine.layout("/jellybeans/index.ssp")
//direct invoking of scalate
}
32
Monday, May 27, 13
GDG Sardegna
Template
SSP
<%@ var body: String %>
<%@ var title: String = "Some Default Title" %>
<%@ var head: String = "" %>
<html>
<head>
<title>${title}</title>
<%-- page specific head goes here --%>
${unescape(head)}
</head>
<body>
<p>layout header goes here...</p>
${unescape(body)}
<p>layout footer goes here...</p>
</body>
</html>
33
Monday, May 27, 13
GDG Sardegna
Template
JADE
!!! 5
html(lang="en")
head
title= pageTitle
:javascript
if (foo) {
bar()
}
body
h1 Jade - node template engine
#container
- if (youAreUsingJade)
p You are amazing
- else
p Get on it!
:coffeescript
alert "Hello, Coffee!"
34
Monday, May 27, 13
GDG Sardegna
Template
Mustache
Hello {{name}}
You have just won ${{value}}!
{{#in_ca}}
Well, ${{taxed_value}}, after taxes.
{{/in_ca}}
35
Monday, May 27, 13
GDG Sardegna
Template
SCAML
!!! XML
!!!
%html
%head
%title Myspace
%body
%h1 I am the international space station
%p Sign my guestbook
36
Monday, May 27, 13
GDG Sardegna
ViewResolver
JSP, JSTL, Tiles, FreeMarker, XSLT, PDF, Velocity, JExcelApi,
JSON, Atom, RSS, JasperReports
Explicit view with different ViewResolver with different order
values, or with ContentTypeNegotiationViewResolver
mapping different mediaTypes
37
Monday, May 27, 13
GDG Sardegna
Authentication & Security
Scalatra uses Scentry a porting of Ruby Warden authentication
class OurAuthStrategy(protected override val app: ScalatraBase, realm: String)
extends BasicAuthStrategy[User](app, realm) {
protected def validate(userName: String, password: String): Option[User] = {
if(userName == "myusername" && password == "secret") Some(User("myusername"))
else None
}
protected def getUserId(user: User): String = user.id
}
case class User(id: String)
38
Monday, May 27, 13
GDG Sardegna
Authentication & Security
Now we need to combine our strategy and ScentrySupport
trait AuthenticationSupport extends ScentrySupport[User] with BasicAuthSupport[User] {
self: ScalatraBase =>
val realm = "Scalatra Basic Auth Example"
protected def fromSession = { case id: String => User(id) }
protected def toSession = { case usr: User => usr.id }
protected val scentryConfig = (new ScentryConfig {}).asInstanceOf[ScentryConfiguration]
}
39
Monday, May 27, 13
GDG Sardegna
Authentication & Security
Now we need to combine our strategy and ScentrySupport
trait AuthenticationSupport extends ScentrySupport[User] with BasicAuthSupport[User] {
....
override protected def configureScentry = {
scentry.unauthenticated {
scentry.strategies("Basic").unauthenticated()
scentry.strategies("")
}
}
override protected def registerAuthStrategies = {
scentry.register("Basic", app => new OurBasicAuthStrategy(app, realm))
}
protected def validate(userName: String, password: String): Option[User] = {
if(userName == "scalatra" && password == "scalatra") Some(User("scalatra"))
else None
}
}
40
Monday, May 27, 13
GDG Sardegna
Authentication & Security
Now we can use the Authentication for all routes defined in our Authenticated Servlets
class AuthenticatedServlet extends ScalatraServlet with AuthenticationSupport{
//every route goes under authentication
}
Unauthenticated user will see a browser prompt login
41
Monday, May 27, 13
GDG Sardegna
SpringSecurity
FilterServlet to protect urls, roles and AOP intercepting based on User Roles
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<sec:http>
" " <sec:form-login login-page="/login.jsp"
login-processing-url="/j_security_check"
default-target-url="/"
" " " always-use-default-target="true"
authentication-failure-url="/loginError.jsp"/>
" " <sec:logout logout-url="/logout.jsp" invalidate-session="true"
logout-success-url="/login.jsp" />
" " <sec:intercept-url pattern="/styles/**" filters="none"/>
" " <sec:intercept-url pattern="/scripts/**" filters="none"/>
" " <sec:intercept-url pattern="/img/**" filters="none"/>
" " <sec:anonymous username="guest" granted-authority="ROLE_GUEST" />
"
42
Monday, May 27, 13
GDG Sardegna
Test
Test with Specs2
class FrontServletSpec extends ScalatraSpec {
def is =
"GET / on FrontServlet" ^
"should return status 200" ! root200 ^
end
addServlet(classOf[FrontServlet], "/*")
def root200 = get("/") {
status must_== 200
}
}
43
Monday, May 27, 13
GDG Sardegna
Q & A
GTUG Sardegna
44
Monday, May 27, 13
GDG Sardegna
Thanks for your attention!
Massimiliano: @desmax74
GTUG Sardegna
45
Thanks for you attention!
Massimiliano: @desmax74
Monday, May 27, 13

More Related Content

Viewers also liked

Dessi docker kubernetes paas cloud
Dessi docker kubernetes paas cloudDessi docker kubernetes paas cloud
Dessi docker kubernetes paas cloudMassimiliano Dessì
 
The hitchhiker's guide to UXing without a UXer - Chrissy Welsh - Codemotion M...
The hitchhiker's guide to UXing without a UXer - Chrissy Welsh - Codemotion M...The hitchhiker's guide to UXing without a UXer - Chrissy Welsh - Codemotion M...
The hitchhiker's guide to UXing without a UXer - Chrissy Welsh - Codemotion M...Codemotion
 
Microservices in Go_Dessi_Massimiliano_Codemotion_2017_Rome
Microservices in Go_Dessi_Massimiliano_Codemotion_2017_Rome Microservices in Go_Dessi_Massimiliano_Codemotion_2017_Rome
Microservices in Go_Dessi_Massimiliano_Codemotion_2017_Rome Massimiliano Dessì
 
The final words about software estimation
The final words about software estimationThe final words about software estimation
The final words about software estimationAlberto Brandolini
 
The amazing world of Game Design - Emanuele Bolognesi - Codemotion Milan 2016
The amazing world of Game Design - Emanuele Bolognesi - Codemotion Milan 2016The amazing world of Game Design - Emanuele Bolognesi - Codemotion Milan 2016
The amazing world of Game Design - Emanuele Bolognesi - Codemotion Milan 2016Codemotion
 
Event sourcing your React-Redux applications
Event sourcing your React-Redux applicationsEvent sourcing your React-Redux applications
Event sourcing your React-Redux applicationsMaurice De Beijer [MVP]
 

Viewers also liked (8)

Dessi docker kubernetes paas cloud
Dessi docker kubernetes paas cloudDessi docker kubernetes paas cloud
Dessi docker kubernetes paas cloud
 
The busy developer guide to Docker
The busy developer guide to DockerThe busy developer guide to Docker
The busy developer guide to Docker
 
The hitchhiker's guide to UXing without a UXer - Chrissy Welsh - Codemotion M...
The hitchhiker's guide to UXing without a UXer - Chrissy Welsh - Codemotion M...The hitchhiker's guide to UXing without a UXer - Chrissy Welsh - Codemotion M...
The hitchhiker's guide to UXing without a UXer - Chrissy Welsh - Codemotion M...
 
Microservices in Go_Dessi_Massimiliano_Codemotion_2017_Rome
Microservices in Go_Dessi_Massimiliano_Codemotion_2017_Rome Microservices in Go_Dessi_Massimiliano_Codemotion_2017_Rome
Microservices in Go_Dessi_Massimiliano_Codemotion_2017_Rome
 
Event storming recipes
Event storming recipesEvent storming recipes
Event storming recipes
 
The final words about software estimation
The final words about software estimationThe final words about software estimation
The final words about software estimation
 
The amazing world of Game Design - Emanuele Bolognesi - Codemotion Milan 2016
The amazing world of Game Design - Emanuele Bolognesi - Codemotion Milan 2016The amazing world of Game Design - Emanuele Bolognesi - Codemotion Milan 2016
The amazing world of Game Design - Emanuele Bolognesi - Codemotion Milan 2016
 
Event sourcing your React-Redux applications
Event sourcing your React-Redux applicationsEvent sourcing your React-Redux applications
Event sourcing your React-Redux applications
 

Similar to Scala vs Spring MVC comparison

Codemotion 2013 scalatra play spray
Codemotion 2013 scalatra play sprayCodemotion 2013 scalatra play spray
Codemotion 2013 scalatra play sprayrealbot
 
TechDay: Kick Start Your Experience with Android Wear - Mario Viviani
TechDay: Kick Start Your Experience with Android Wear - Mario VivianiTechDay: Kick Start Your Experience with Android Wear - Mario Viviani
TechDay: Kick Start Your Experience with Android Wear - Mario VivianiCodemotion
 
Kick start your experience with android wear - Codemotion Rome 2015
Kick start your experience with android wear - Codemotion Rome 2015Kick start your experience with android wear - Codemotion Rome 2015
Kick start your experience with android wear - Codemotion Rome 2015Codemotion
 
Practical Example of AOP with AspectJ
Practical Example of AOP with AspectJPractical Example of AOP with AspectJ
Practical Example of AOP with AspectJYegor Bugayenko
 
Dependency management & Package management in JavaScript
Dependency management & Package management in JavaScriptDependency management & Package management in JavaScript
Dependency management & Package management in JavaScriptSebastiano Armeli
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your AppLuca Mearelli
 
Big Data processing with Spark, Scala or Java?
Big Data processing with Spark, Scala or Java?Big Data processing with Spark, Scala or Java?
Big Data processing with Spark, Scala or Java?Erik-Berndt Scheper
 
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、GaelykでハンズオンTsuyoshi Yamamoto
 
Private slideshow
Private slideshowPrivate slideshow
Private slideshowsblackman
 
Drupal in aerospace - selling geodetic satellite data with Commerce - Martin ...
Drupal in aerospace - selling geodetic satellite data with Commerce - Martin ...Drupal in aerospace - selling geodetic satellite data with Commerce - Martin ...
Drupal in aerospace - selling geodetic satellite data with Commerce - Martin ...DrupalCamp MSK
 
Magento Dependency Injection
Magento Dependency InjectionMagento Dependency Injection
Magento Dependency InjectionAnton Kril
 
Java 8 Hipster slides
Java 8 Hipster slidesJava 8 Hipster slides
Java 8 Hipster slidesOleg Prophet
 
Struts 2 + Spring
Struts 2 + SpringStruts 2 + Spring
Struts 2 + SpringBryan Hsueh
 
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...Bruno Salvatore Belluccia
 
Agile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with NetbeansAgile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with NetbeansCarol McDonald
 
Knockout.js presentation
Knockout.js presentationKnockout.js presentation
Knockout.js presentationScott Messinger
 
Multi Client Development with Spring - Josh Long
Multi Client Development with Spring - Josh Long Multi Client Development with Spring - Josh Long
Multi Client Development with Spring - Josh Long jaxconf
 

Similar to Scala vs Spring MVC comparison (20)

Codemotion 2013 scalatra play spray
Codemotion 2013 scalatra play sprayCodemotion 2013 scalatra play spray
Codemotion 2013 scalatra play spray
 
TechDay: Kick Start Your Experience with Android Wear - Mario Viviani
TechDay: Kick Start Your Experience with Android Wear - Mario VivianiTechDay: Kick Start Your Experience with Android Wear - Mario Viviani
TechDay: Kick Start Your Experience with Android Wear - Mario Viviani
 
Kick start your experience with android wear - Codemotion Rome 2015
Kick start your experience with android wear - Codemotion Rome 2015Kick start your experience with android wear - Codemotion Rome 2015
Kick start your experience with android wear - Codemotion Rome 2015
 
Practical Example of AOP with AspectJ
Practical Example of AOP with AspectJPractical Example of AOP with AspectJ
Practical Example of AOP with AspectJ
 
Dependency management & Package management in JavaScript
Dependency management & Package management in JavaScriptDependency management & Package management in JavaScript
Dependency management & Package management in JavaScript
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your App
 
Big Data processing with Spark, Scala or Java?
Big Data processing with Spark, Scala or Java?Big Data processing with Spark, Scala or Java?
Big Data processing with Spark, Scala or Java?
 
Test upload
Test uploadTest upload
Test upload
 
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
 
Private slideshow
Private slideshowPrivate slideshow
Private slideshow
 
Drupal in aerospace - selling geodetic satellite data with Commerce - Martin ...
Drupal in aerospace - selling geodetic satellite data with Commerce - Martin ...Drupal in aerospace - selling geodetic satellite data with Commerce - Martin ...
Drupal in aerospace - selling geodetic satellite data with Commerce - Martin ...
 
World of CSS Grid
World of CSS GridWorld of CSS Grid
World of CSS Grid
 
Magento Dependency Injection
Magento Dependency InjectionMagento Dependency Injection
Magento Dependency Injection
 
Java 8 Hipster slides
Java 8 Hipster slidesJava 8 Hipster slides
Java 8 Hipster slides
 
Struts 2 + Spring
Struts 2 + SpringStruts 2 + Spring
Struts 2 + Spring
 
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
 
Modular and Event-Driven JavaScript
Modular and Event-Driven JavaScriptModular and Event-Driven JavaScript
Modular and Event-Driven JavaScript
 
Agile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with NetbeansAgile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with Netbeans
 
Knockout.js presentation
Knockout.js presentationKnockout.js presentation
Knockout.js presentation
 
Multi Client Development with Spring - Josh Long
Multi Client Development with Spring - Josh Long Multi Client Development with Spring - Josh Long
Multi Client Development with Spring - Josh Long
 

More from Massimiliano Dessì

When Old Meets New: Turning Maven into a High Scalable, Resource Efficient, C...
When Old Meets New: Turning Maven into a High Scalable, Resource Efficient, C...When Old Meets New: Turning Maven into a High Scalable, Resource Efficient, C...
When Old Meets New: Turning Maven into a High Scalable, Resource Efficient, C...Massimiliano Dessì
 
Web Marketing Training 2014 Community Online
Web Marketing Training 2014 Community OnlineWeb Marketing Training 2014 Community Online
Web Marketing Training 2014 Community OnlineMassimiliano Dessì
 
Three languages in thirty minutes
Three languages in thirty minutesThree languages in thirty minutes
Three languages in thirty minutesMassimiliano Dessì
 
Jaxitalia09 Spring Best Practices
Jaxitalia09 Spring Best PracticesJaxitalia09 Spring Best Practices
Jaxitalia09 Spring Best PracticesMassimiliano Dessì
 
MongoDB Scala Roma SpringFramework Meeting2009
MongoDB Scala Roma SpringFramework Meeting2009MongoDB Scala Roma SpringFramework Meeting2009
MongoDB Scala Roma SpringFramework Meeting2009Massimiliano Dessì
 
Scala Programming Linux Day 2009
Scala Programming Linux Day 2009Scala Programming Linux Day 2009
Scala Programming Linux Day 2009Massimiliano Dessì
 
MongoDB SpringFramework Meeting september 2009
MongoDB SpringFramework Meeting september 2009MongoDB SpringFramework Meeting september 2009
MongoDB SpringFramework Meeting september 2009Massimiliano Dessì
 
The hidden gems of Spring Security
The hidden gems of Spring SecurityThe hidden gems of Spring Security
The hidden gems of Spring SecurityMassimiliano Dessì
 
Aspect Oriented Programming and MVC with Spring Framework
Aspect Oriented Programming and MVC with Spring FrameworkAspect Oriented Programming and MVC with Spring Framework
Aspect Oriented Programming and MVC with Spring FrameworkMassimiliano Dessì
 
Real Spring Aop Recipes For Your Everyday Job
Real Spring Aop Recipes For Your Everyday JobReal Spring Aop Recipes For Your Everyday Job
Real Spring Aop Recipes For Your Everyday JobMassimiliano Dessì
 

More from Massimiliano Dessì (20)

Code One 2018 maven
Code One 2018   mavenCode One 2018   maven
Code One 2018 maven
 
When Old Meets New: Turning Maven into a High Scalable, Resource Efficient, C...
When Old Meets New: Turning Maven into a High Scalable, Resource Efficient, C...When Old Meets New: Turning Maven into a High Scalable, Resource Efficient, C...
When Old Meets New: Turning Maven into a High Scalable, Resource Efficient, C...
 
Hacking Maven Linux day 2017
Hacking Maven Linux day 2017Hacking Maven Linux day 2017
Hacking Maven Linux day 2017
 
Web Marketing Training 2014 Community Online
Web Marketing Training 2014 Community OnlineWeb Marketing Training 2014 Community Online
Web Marketing Training 2014 Community Online
 
Scala linux day 2012
Scala linux day 2012 Scala linux day 2012
Scala linux day 2012
 
Three languages in thirty minutes
Three languages in thirty minutesThree languages in thirty minutes
Three languages in thirty minutes
 
MongoDB dessi-codemotion
MongoDB dessi-codemotionMongoDB dessi-codemotion
MongoDB dessi-codemotion
 
MongoDB Webtech conference 2010
MongoDB Webtech conference 2010MongoDB Webtech conference 2010
MongoDB Webtech conference 2010
 
RESTEasy
RESTEasyRESTEasy
RESTEasy
 
Spring Roo Internals Javaday IV
Spring Roo Internals Javaday IVSpring Roo Internals Javaday IV
Spring Roo Internals Javaday IV
 
Spring Roo JaxItalia09
Spring Roo JaxItalia09Spring Roo JaxItalia09
Spring Roo JaxItalia09
 
Jaxitalia09 Spring Best Practices
Jaxitalia09 Spring Best PracticesJaxitalia09 Spring Best Practices
Jaxitalia09 Spring Best Practices
 
Spring3.0 JaxItalia09
Spring3.0 JaxItalia09Spring3.0 JaxItalia09
Spring3.0 JaxItalia09
 
MongoDB Scala Roma SpringFramework Meeting2009
MongoDB Scala Roma SpringFramework Meeting2009MongoDB Scala Roma SpringFramework Meeting2009
MongoDB Scala Roma SpringFramework Meeting2009
 
Scala Programming Linux Day 2009
Scala Programming Linux Day 2009Scala Programming Linux Day 2009
Scala Programming Linux Day 2009
 
MongoDB SpringFramework Meeting september 2009
MongoDB SpringFramework Meeting september 2009MongoDB SpringFramework Meeting september 2009
MongoDB SpringFramework Meeting september 2009
 
The hidden gems of Spring Security
The hidden gems of Spring SecurityThe hidden gems of Spring Security
The hidden gems of Spring Security
 
Spring @Aspect e @Controller
Spring @Aspect e @Controller Spring @Aspect e @Controller
Spring @Aspect e @Controller
 
Aspect Oriented Programming and MVC with Spring Framework
Aspect Oriented Programming and MVC with Spring FrameworkAspect Oriented Programming and MVC with Spring Framework
Aspect Oriented Programming and MVC with Spring Framework
 
Real Spring Aop Recipes For Your Everyday Job
Real Spring Aop Recipes For Your Everyday JobReal Spring Aop Recipes For Your Everyday Job
Real Spring Aop Recipes For Your Everyday Job
 

Recently uploaded

Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsSnow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsHyundai Motor Group
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 

Recently uploaded (20)

Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsSnow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 

Scala vs Spring MVC comparison

  • 1. Scala Italy 25 may 2013 Scalatra comparison with SpringMVC Massimiliano Dessì 1 Monday, May 27, 13
  • 2. GDG Sardegna Speaker Max has more than 13 years of experience in programming. He’s a proud father of three. Manager of GTUG Sardegna, Founder of SpringFramework IT, co-founder of Jug Sardegna. Author of Spring 2.5 AOP. He works in Energeya as a Product Architect and lives in Cagliari, Italy. 2 Monday, May 27, 13
  • 3. GDG Sardegna Scalatra - SpringMVC CRUD HTML REST JSON Routing Template Security Agenda 3 Monday, May 27, 13
  • 4. GDG Sardegna Spring , Since 2004 - Java Full Stack - Lot of people involved now property of VMware Scalatra , Since 2009 - Scala Http Microframework (DSL) the BBC, LinkedIn, the Guardian, games website IGN, UK government rely on Scalatra. Some info 4 Monday, May 27, 13
  • 5. GDG Sardegna REST class JellyBeans extends ScalatraServlet { get("/jellybs/:id") { ... } post("/jellybs") { ... } put("/jellybs/:id") { ... } delete("/jellybs/:id") { ... } } For browser add PUT & DELETE support client side X-HTTP-METHOD-OVERRIDE or _method=put _method=delete in the post body class JellyBeansBrowser extends ScalatraFilter with MethodOverride 5 Monday, May 27, 13
  • 6. GDG SardegnaMassimiliano Dessì Routes class JellyBeans extends ScalatraServlet { get("/jellybs/:id") { val id:Int = params.getOrElse("id", halt(400)).toInt ... } get("/jellybs/download/*.*") { //with wildcard ... } get("""^/j(.*)/f(.*)""".or) { //REGEX ... } post("/jellybs", request.getRemoteHost == "127.0.0.1", request.getRemoteUser == "admin") { .... } 6 Monday, May 27, 13
  • 7. GDG Sardegna REST @Controller public class JellyBeansController{ @RequestMapping(value = "/jellybs/{id}", method = RequestMethod.GET) @ResponseStatus(HttpStatus.OK) //Http 200 public @ResponseBody JellyB getItem(@PathVariable("id") Integer id) {...} @RequestMapping(value = "/jellybs", method = RequestMethod.POST) //Http 201 @ResponseStatus(HttpStatus.CREATED) //Http 201 public void createJelly(HttpServletRequest req, HttpServletResponse res, @RequestBody JellyB item) { ... } @RequestMapping(value = "/jellybs/{id}", method = RequestMethod.PUT) @ResponseStatus(HttpStatus.NO_CONTENT) //Http 204 public void updateItem(@RequestBody JellyB item, @PathVariable("id") Integer id) { ... } @RequestMapping(value = "/items/{id}", method = RequestMethod.DELETE) @ResponseStatus(HttpStatus.NO_CONTENT)//204 public void deleteItem(@PathVariable("id") String id) { ... } } For browser add PUT & DELETE support client side X-HTTP-METHOD-OVERRIDE or _method=put _method=delete in the post body <filter> <filter-name>hiddenMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> 7 Monday, May 27, 13
  • 8. GDG Sardegna Routes class JellyBeans extends ScalatraServlet { get("/jellybs/:id") { val id:Int = params.getOrElse("id", halt(400)).toInt ... } get("/jellybs/download/*.*") { //with wildcard ... } get("""^/j(.*)/f(.*)""".or) { //REGEX ... } post("/jellybs", request.getRemoteHost == "127.0.0.1", request.getRemoteUser == "admin") { .... } 8 Monday, May 27, 13
  • 9. GDG Sardegna HandlerMapping @Controller public class JellyBeansController{ @RequestMapping(value="/jelly.pdf",method = RequestMethod.GET) public ModelAndView pdf(HttpServletRequest req,@RequestParam String id) { ... } @RequestMapping(value = "/jellybs/{id}", method = RequestMethod.GET) public String getItem(@PathVariable("id") Integer id) { ... } @RequestMapping(value = "/jellybs", method = RequestMethod.POST) public void createJelly(@ModelAttribute(”jelly”) JellyB jelly) { ... } } DefaultAnnotationHandlerMapping SimpleUrlHandlerMapping ControllerClassNameHandlerMapping 9 Monday, May 27, 13
  • 10. GDG Sardegna Filter class JellyBeans extends ScalatraServlet { before() { db.acquireConnecion contentType="text/html" } get("/") { val menu = db.findWelcome() templateEngine.layout("index.ssp", menu) } after() { db.releaseConnection } } Like Servlet Filter (or Aspect Oriented Programming) You can add logic before or the routes 10 Monday, May 27, 13
  • 11. GDG Sardegna Handler Interceptor public interface HandlerInterceptor{ //before call method’s controller boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception; //after call method’s controller void postHandle(HttpServletRequest req, HttpServletResponse res, Object handler, ModelAndView mav) throws Exception; //after view render() void afterCompletition(HttpServletRequest req, HttpServletResponse res, Object handler, Exception ex) throws Exception; } Handler mapped on all controllers (as a property of Handlermapping config) or mapped on url path with <mvc:interceptors> tags Like Servlet Filter (or Aspect Oriented Programming) You can add logic before or after the controllers methods 11 Monday, May 27, 13
  • 12. GDG Sardegna Handlers Handlers are top level methods for http routines class JellyBeans extends ScalatraServlet { notFound { <h1>Not found</h1> } halt(status = 301, headers = Map("Location" -> "http://www.codemotion.com/")) get("/jellybs/names/*") { "Name not found!" } } 12 Monday, May 27, 13
  • 13. GDG Sardegna Handlers class JellyBeans extends ScalatraServlet { get("/jellybs/names/:who") { params("who") match { case "Cherry" => "Found Cherry!" case _ => pass() /* call the next matching route route, routes are matched from bottom up*/ } } get("/jellybs/download/:id") { jellyBeanService.find(params("id")) match { case Some(jellybean) => Ok(jellybean) case None => NotFound("Sorry, jellybean not found") } } } 13 Monday, May 27, 13
  • 14. GDG Sardegna Request Response & Friends class JellyBeans extends ScalatraServlet { get("/jellybs/shows/:id") { //access to request,response, session and params request.body //request body as a string request.cookies // cookie map request.isAjax // is ajaxRequest request.getSession // HttpServletSession request.locale // user locale response.getOutputStream //response outputstream servletContext.get("myIntParam") //servlet context val idString = params("id") val id = params.getAs[Int]("id") //val id = params.getOrElse("id", halt(500)) //another way .... } } 14 Monday, May 27, 13
  • 15. GDG Sardegna Request Response & Friends class JellyBeans extends ScalatraServlet { get("/jellybs/*/conf/*") { // Matches "GET /jellybs/one/conf/two" multiParams("splat") // Seq("one", "two") //wildcard accessible with key splat } get("""^/jelly(.*)/fla(.*)""".r) { // Matches "GET /jellybs/flavor" multiParams("captures") // == Seq("bs", "vor") } } 15 Monday, May 27, 13
  • 16. GDG Sardegna Gzip class GzipJellyBeans extends ScalatraServlet with GZipSupport{ get("/") { <html> <body> <h1>This is <a href="http://en.wikipedia.org/wiki/Sparta">Sparta</a>! </h1> </body> </html> } } 16 Monday, May 27, 13
  • 17. GDG Sardegna Flash message class FlashServlet extends ScalatraServlet with FlashMapSupport{ post("/jellybs/create") { flash("notice") = "jellybean created successfully" redirect("/home") //redirect } get("/home") { ssp("/home") //Scala Server Pages } 17 Monday, May 27, 13
  • 18. GDG Sardegna ExceptionResolvers <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="org.springframework.web.HttpSessionRequiredException">welcome</prop> ... </props> </property> </bean> or in a annotated @Controller class @ExceptionHandler public String requestParamNotPresent(HttpMediaTypeException ex) 18 Monday, May 27, 13
  • 19. GDG Sardegna Binding To avoid manual binding from http and our Object Scalatra provide a binding module case class MyClass(id: Integer, name: String) post("/myroute") { val cmd = command[CreateMyClassCommand] ... } 19 Monday, May 27, 13
  • 20. GDG Sardegna Binding Under the hood abstract class MyClassCommand[S](implicit mf: Manifest[S]) extends ModelCommand[S] with JsonCommand {    implicit def todoStringValidators(b: FieldDescriptor[String]) = new MyClassStringValidations(b) } class CreateMyClassCommand extends MyClassCommand[MyClass] { protected implicit val jsonFormats = DefaultFormats val name: Field[String] = asType[String]("name").notBlank.minLength(3) } 20 Monday, May 27, 13
  • 21. GDG Sardegna Binding Under the hood class MyClassStringValidations(b: FieldDescriptor[String]) { def startsWithCap(message: String = "%s must start with a capital letter.") = b.validateWith(_ =>      _ flatMap { new PredicateValidator[String]( b.name, """^[A-Z,0-9]""".r.findFirstIn(_).isDefined, message).validate(_)    ) } ) } 21 Monday, May 27, 13
  • 22. GDG Sardegna CommandObject @RequestMapping(value = "/items/{id}", method = RequestMethod.PUT) @ResponseStatus(HttpStatus.NO_CONTENT) public String updateItem(JellyB item) { ... } Spring bind the request body on the object used in the method (JellyB) Objects Validation with jsr 303 annotation or with Validator Spring Interface Error message with JSP/JSTL tags 22 Monday, May 27, 13
  • 23. GDG Sardegna Upload import org.scalatra.ScalatraServlet import org.scalatra.servlet.FileUploadSupport import javax.servlet.annotation.MultipartConfig @MultipartConfig(maxFileSize=10*1024) trait StorageRoutes extends FileUploadSupport { self: ScalatraServlet => } 23 Monday, May 27, 13
  • 24. GDG Sardegna JSON Automatic Serialization and deserialization of any Case class object JSONServlet extends ScalatraServlet with JacksonJsonSupport{ case class JellyBean(id: Int, name: String, flavor:String) protected implicit val jsonFormats: Formats = DefaultFormats before() { contentType = formats("json") } .... 24 Monday, May 27, 13
  • 25. GDG Sardegna Actors The routes can returns a Future class MyActorServlet(system:ActorSystem, myActor:ActorRef) extends ScalatraServlet with FutureSupport { import _root_.akka.pattern.ask implicit val timeout = Timeout(10) protected implicit def executor: ExecutionContext = system.dispatcher get("/async") { myActor ? "Do stuff and give me an answer" } get("/fire-forget") { myActor ! "Hey, you know what?" Accepted() //if you do not want return a future } } 25 Monday, May 27, 13
  • 26. GDG Sardegna Actors get("/async") { myActor ? "Do stuff and give me an answer" } get("/fire-forget") { myActor ! "Hey, you know what?" Accepted() //if you don’t want return a future } class CodemotionActor extends Actor { def receive = { case "Do stuff and give me an answer" => sender ! "The answer is 42" case "Hey, you know what?" => println("Yeah I know...") } } } 26 Monday, May 27, 13
  • 27. GDG Sardegna Akka Akka start in the Bootstrap of Scalatra class ScalatraBootstrap extends LifeCycle { val system = ActorSystem() val codemotionActor = system.actorOf(Props[CodemotionActor]) override def init(context: ServletContext) { context.mount(new JSONServlet, "/jellybs/*") context.mount(new FrontServlet, "/template/*") context.mount(new MyActorServlet(system, codemotionActor), "/actors/*") } override def destroy(context:ServletContext) { system.shutdown() } } 27 Monday, May 27, 13
  • 28. GDG Sardegna Deployment Scalatra is based on regular Java Servlet 3.0 it can start from: Standalone from jetty embedded From Servlet container Heroku Jelastic CloudBees GAE (not out of the box ) web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <listener> <listener-class>org.scalatra.servlet.ScalatraListener</listener-class> </listener> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/img/*</url-pattern> <url-pattern>/css/*</url-pattern> <url-pattern>/js/*</url-pattern> <url-pattern>/assets/*</url-pattern> </servlet-mapping> </web-app> 28 Monday, May 27, 13
  • 29. GDG Sardegna JSON Automatic Serialization and deserialization of any Case class object JSONServlet extends ScalatraServlet with JacksonJsonSupport{ ... get("/jellybs/all"){ jellyBeanRepo.all //from class to json } post("/jellybs/create") { val jb = parsedBody.extract[JellyBean] //from json to class ... } } 29 Monday, May 27, 13
  • 30. GDG Sardegna JSON 30 JSON with third party lib es Jackson @JsonCreator public JellyB(Map map) {...} @JsonAnyGetter public Map toMap() {...} Automatic binding public @ResponseBody JellyB getItem(...) public void updateItem(@RequestBody JellyB item) Monday, May 27, 13
  • 31. GDG Sardegna Template Html inline, Scalate Twirl (Play2 template) Scalate mean SSP (Scala Server Page) Scaml Mustache Jade 31 Monday, May 27, 13
  • 32. GDG Sardegna Template class ScalateServlet extends ScalatraServlet with ScalateSupport{ get("/"jellybeans/ssp) { contentType="text/html" ssp("/index", "foo" -> "uno", "bar" -> "two") // the layout used it’s WEB-INF/layouts/default.ssp } get("/jellybeans/jade") { jade("/index", "layout" -> "", "foo" -> "one", "bar" -> "two") // render without a layout. } get("/jellybeans/direct") { templateEngine.layout("/jellybeans/index.ssp") //direct invoking of scalate } 32 Monday, May 27, 13
  • 33. GDG Sardegna Template SSP <%@ var body: String %> <%@ var title: String = "Some Default Title" %> <%@ var head: String = "" %> <html> <head> <title>${title}</title> <%-- page specific head goes here --%> ${unescape(head)} </head> <body> <p>layout header goes here...</p> ${unescape(body)} <p>layout footer goes here...</p> </body> </html> 33 Monday, May 27, 13
  • 34. GDG Sardegna Template JADE !!! 5 html(lang="en") head title= pageTitle :javascript if (foo) { bar() } body h1 Jade - node template engine #container - if (youAreUsingJade) p You are amazing - else p Get on it! :coffeescript alert "Hello, Coffee!" 34 Monday, May 27, 13
  • 35. GDG Sardegna Template Mustache Hello {{name}} You have just won ${{value}}! {{#in_ca}} Well, ${{taxed_value}}, after taxes. {{/in_ca}} 35 Monday, May 27, 13
  • 36. GDG Sardegna Template SCAML !!! XML !!! %html %head %title Myspace %body %h1 I am the international space station %p Sign my guestbook 36 Monday, May 27, 13
  • 37. GDG Sardegna ViewResolver JSP, JSTL, Tiles, FreeMarker, XSLT, PDF, Velocity, JExcelApi, JSON, Atom, RSS, JasperReports Explicit view with different ViewResolver with different order values, or with ContentTypeNegotiationViewResolver mapping different mediaTypes 37 Monday, May 27, 13
  • 38. GDG Sardegna Authentication & Security Scalatra uses Scentry a porting of Ruby Warden authentication class OurAuthStrategy(protected override val app: ScalatraBase, realm: String) extends BasicAuthStrategy[User](app, realm) { protected def validate(userName: String, password: String): Option[User] = { if(userName == "myusername" && password == "secret") Some(User("myusername")) else None } protected def getUserId(user: User): String = user.id } case class User(id: String) 38 Monday, May 27, 13
  • 39. GDG Sardegna Authentication & Security Now we need to combine our strategy and ScentrySupport trait AuthenticationSupport extends ScentrySupport[User] with BasicAuthSupport[User] { self: ScalatraBase => val realm = "Scalatra Basic Auth Example" protected def fromSession = { case id: String => User(id) } protected def toSession = { case usr: User => usr.id } protected val scentryConfig = (new ScentryConfig {}).asInstanceOf[ScentryConfiguration] } 39 Monday, May 27, 13
  • 40. GDG Sardegna Authentication & Security Now we need to combine our strategy and ScentrySupport trait AuthenticationSupport extends ScentrySupport[User] with BasicAuthSupport[User] { .... override protected def configureScentry = { scentry.unauthenticated { scentry.strategies("Basic").unauthenticated() scentry.strategies("") } } override protected def registerAuthStrategies = { scentry.register("Basic", app => new OurBasicAuthStrategy(app, realm)) } protected def validate(userName: String, password: String): Option[User] = { if(userName == "scalatra" && password == "scalatra") Some(User("scalatra")) else None } } 40 Monday, May 27, 13
  • 41. GDG Sardegna Authentication & Security Now we can use the Authentication for all routes defined in our Authenticated Servlets class AuthenticatedServlet extends ScalatraServlet with AuthenticationSupport{ //every route goes under authentication } Unauthenticated user will see a browser prompt login 41 Monday, May 27, 13
  • 42. GDG Sardegna SpringSecurity FilterServlet to protect urls, roles and AOP intercepting based on User Roles <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <sec:http> " " <sec:form-login login-page="/login.jsp" login-processing-url="/j_security_check" default-target-url="/" " " " always-use-default-target="true" authentication-failure-url="/loginError.jsp"/> " " <sec:logout logout-url="/logout.jsp" invalidate-session="true" logout-success-url="/login.jsp" /> " " <sec:intercept-url pattern="/styles/**" filters="none"/> " " <sec:intercept-url pattern="/scripts/**" filters="none"/> " " <sec:intercept-url pattern="/img/**" filters="none"/> " " <sec:anonymous username="guest" granted-authority="ROLE_GUEST" /> " 42 Monday, May 27, 13
  • 43. GDG Sardegna Test Test with Specs2 class FrontServletSpec extends ScalatraSpec { def is = "GET / on FrontServlet" ^ "should return status 200" ! root200 ^ end addServlet(classOf[FrontServlet], "/*") def root200 = get("/") { status must_== 200 } } 43 Monday, May 27, 13
  • 44. GDG Sardegna Q & A GTUG Sardegna 44 Monday, May 27, 13
  • 45. GDG Sardegna Thanks for your attention! Massimiliano: @desmax74 GTUG Sardegna 45 Thanks for you attention! Massimiliano: @desmax74 Monday, May 27, 13