SlideShare a Scribd company logo
1 of 109
Download to read offline
Agile Development with CDI 
in a Java EE World
R. Turini 
Java EE Instructor 
VRaptor lead developer
Chico 
Sokol
Java training 
Community 
Open Source!
What is 
VRaptor ?
MVC 
web framework 
Action-based
Why 
VRaptor ?
Simple Flexible 
Open Source
JSR-371 
MVC 1.0
CDI
CDI + JavaEE 7
VRaptor 
basics
@Controller 
public class SpeakerController { 
@Inject private SpeakerDao speakerDao; 
@Inject private Result result; 
@Get("speaker/add") 
public void add() {} 
@Post("speaker/add") 
public void add(Speaker speaker) { 
speakerDao.save(speaker); 
result.redirectTo(this).list(); 
} 
public void list() { 
result.include("speakers", speakerDao.list()); 
} 
}
Serious 
CoC
@Controller 
public class SpeakerController { 
public void add() { 
} 
}
@Controller 
public class SpeakerController { 
speaker/add 
pattern: controllerName/methodName 
public void add() { 
} 
}
@Controller 
public class SpeakerController { 
speaker/add 
pattern: controllerName/methodName 
public void add() { 
} 
} 
/WEB-INF/jsp/speaker/add.jsp 
pattern: /WEB-INF/jsp/controllerName/methodName.jsp
Methods with the same name ?
@Controller 
public class SpeakerController { 
public void add() { 
} 
public void add(Speaker speaker) { 
speakerDao.save(speaker); 
} 
} 
speaker/add
URL 
ambiguity
@Controller 
public class SpeakerController { 
public void add() { 
} 
public void add(Speaker speaker) { 
speakerDao.save(speaker); 
} 
}
@Controller 
public class SpeakerController { 
@Path("/speaker/form") 
public void add() { 
} 
@Path("/speaker/add") 
public void add(Speaker speaker) { 
speakerDao.save(speaker); 
} 
} 
explicitly defining the path, using: 
@Path("/your/custom/path")
@Controller 
public class SpeakerController { 
@Get 
public void add() { 
} 
@Post 
public void add(Speaker speaker) { 
speakerDao.save(speaker); 
} 
} 
limit access to a controller method 
acording with the HTTP verb, using: 
@Get, @Post, @Put or @Delete
@Controller 
public class SpeakerController { 
@Get("/speaker/form") 
public void add() { 
} 
@Post("/speaker/add") 
public void add(Speaker speaker) { 
speakerDao.save(speaker); 
} 
} 
Or both! 
@Get("/your/custom/path")
Parameter 
injection
@Controller 
public class SpeakerController { 
// other methods 
@Post("/speaker/add") 
public void add(Speaker speaker) { 
speakerDao.save(speaker); 
} 
}
@Controller 
public class SpeakerController { 
// other methods 
@Post("/speaker/add") 
public void add(String name, int age) { 
Speaker speaker = new Speaker(name, age); 
speakerDao.save(speaker); 
} 
}
@Controller 
public class SpeakerController { 
// other methods 
@Post("/speaker/add") 
public void add(String name, int age) { 
Speaker speaker = new Speaker(name, age); 
speakerDao.save(speaker); 
} 
} 
<form action="/speaker/add" method="post"> 
Name: <input name="name"> 
Age: <input name="age"> 
<input type="submit"> 
</form>
@Controller 
public class SpeakerController { 
// other methods 
@Post("/speaker/add") 
public void add(Speaker speaker) { 
Speaker speaker = new Speaker(name, age); 
speakerDao.save(speaker); 
} 
}
@Controller 
public class SpeakerController { 
// other methods 
@Post("/speaker/add") 
public void add(Speaker speaker) { 
Speaker speaker = new Speaker(name, age); 
speakerDao.save(speaker); 
<form action="/speaker/add" method="post"> 
Name: <input name="speaker.name"> 
Age: <input name="speaker.age"> 
<input type="submit"> 
</form> 
} 
}
Name: <input name="speaker.name"> 
Age: <input name="speaker.age"> 
?speaker.name=Chico&speaker.age=26 
new Speaker("Chico", 26)
Name: <input name="speaker.name"> 
?speaker.name=Chico 
speaker.setName("Chico")
Redirecting 
to another logic
@Controller 
public class SpeakerController { 
@Post("/speaker/add") 
public void add(Speaker speaker) { 
speakerDao.save(speaker); 
// must redirect to list method 
} 
public void list() { 
// include something to the view 
} 
}
@Controller 
public class SpeakerController { 
@Post("/speaker/add") 
public void add(Speaker speaker) { 
speakerDao.save(speaker); 
result.redirectTo("/speaker/list"); 
} 
public void list() { 
// including something to the view 
} 
}
@Controller 
public class SpeakerController { 
@Post("/speaker/add") 
public void add(Speaker speaker) { 
speakerDao.save(speaker); 
result.redirectTo(this).list(); 
} 
public void list() { 
// including something to the view 
} 
}
DI
@Controller 
public class SpeakerController { 
@Inject private Result result; 
@Post("/speaker/add") 
public void add(Speaker speaker) { 
speakerDao.save(speaker); 
result.redirectTo(this).list(); 
} 
public void list() { 
// including something to the view 
} 
}
@Controller 
public class SpeakerController { 
@Inject private Result result; 
@Post("/speaker/add") 
public void add(Speaker speaker) { 
speakerDao.save(speaker); 
result.redirectTo(this).list(); 
} 
public void list() { 
// including something to the view 
} 
}
including 
attributes
@Controller 
public class SpeakerController { 
@Inject private Result result; 
@Post("/speaker/add") 
public void add(Speaker speaker) { 
speakerDao.save(speaker); 
result.redirectTo(this).list(); 
} 
@Get("speaker/list") 
public void list() { 
result.include("speakers", speakerDao.list()); 
} 
}
public void list() { 
result.include("speakers", speakerDao.list()); 
} 
<html> 
<body> 
<ul> 
<c:forEach items="${speakers}" var="speaker"> 
<li>${speaker.name}</li> 
</c:forEach> 
</ul> 
</body> 
</html>
SERVICES ? what about
public void list() { 
result.use(Results.json()) 
.from(speakerDao.list()).serialize(); 
} 
{"list":[ 
{"name":"Rodrigo Turini", ...}, 
{"name":"Chico Sokol", ...} 
]}
public void list() { 
result.use(Results.xml()) 
.from(speakerDao.list()).serialize(); 
<list> 
<speaker> 
<name>Rodrigo Turini</name> ... 
</speaker> 
<speaker> 
<name>Chico Sokol</name> ... 
</speaker> 
</list> 
}
Taking advantage of 
CDI
Inject 
ANY 
bean
public class SpeakerDao { 
public void save(Speaker speaker) { 
//persist our speaker 
} 
public List<Speaker> list() { 
//return all speakers from db 
} 
}
@RequestScoped 
public class SpeakerDao { 
public void save(Speaker speaker) { 
//persist our speaker 
Any annotated class is a CDI Bean 
} 
public List<Speaker> list() { 
//return all speakers from db 
} 
}
@RequestScoped 
public class SpeakerDao { 
//... 
} 
@Controller 
public class SpeakerController { 
@Inject 
private SpeakerDao speakerDao; 
@Post("/speaker/add") 
public void add(Speaker speaker) { 
speakerDao.save(speaker); 
} 
}
Inject 
third party 
classes
@RequestScoped 
public class SpeakerDao { 
private EntityManager em; 
public void save(Speaker speaker) { 
em.persist(speaker); 
} 
}
@RequestScoped 
public class SpeakerDao { 
@Inject 
private EntityManager em; 
public void save(Speaker speaker) { 
em.persist(speaker); 
} 
}
@RequestScoped 
public class SpeakerDao { 
@Inject 
private EntityManager em; 
public void save(Speaker speaker) { 
em.persist(speaker); 
} 
} 
EntityManager isn't a CDI bean!
@Produces @RequestScoped 
public EntityManager produce() { 
return emf.createEntityManager(); 
}
@ApplicationScoped 
public class EntityManagerProducer { 
private EntityManagerFactory emf; 
@PostConstruct 
public void init() { 
emf = // initializing EM factory 
} 
@Produces @RequestScoped 
public EntityManager produce() { 
return emf.createEntityManager(); 
} 
}
what about 
TRANSACTIONS ?
@RequestScoped 
public class SpeakerDao { 
@Inject private EntityManager em; 
public void save(Speaker speaker) { 
em.getTransaction().begin(); 
em.persist(speaker); 
em.getTransaction().commit(); 
} 
}
CDI’s 
Interceptor
@InterceptorBinding 
@Target({METHOD,TYPE}) 
@Retention(RUNTIME) 
public @interface UsingTransaction { 
}
@Interceptor @UsingTransaction 
@Priority(100) 
public class TransactionalInterceptor { 
@Inject private EntityManager em; 
@AroundInvoke 
public Object intercept(InvocationContext context) 
throws Exception { 
em.getTransaction().begin(); 
Object proceed = context.proceed(); 
em.getTransaction().commit(); 
return proceed; 
} 
}
@RequestScoped 
public class SpeakerDao { 
@Inject private EntityManager em; 
public void save(Speaker speaker) { 
em.getTransaction().begin(); 
em.persist(speaker); 
em.getTransaction().commit(); 
} 
}
@RequestScoped 
public class SpeakerDao { 
@Inject private EntityManager em; 
@UsingTransaction 
public void save(Speaker speaker) { 
em.getTransaction().begin(); 
em.persist(speaker); 
em.getTransaction().commit(); 
} 
}
CDI’s Events
You can observe 
VRaptor 
events
@ApplicationScoped 
public class VRaptorStartupObserver { 
public void init(@Observes VRaptorInitialized event){ 
// send email notifying deploy 
} 
}
@ApplicationScoped 
public class VRaptorStartupObserver { 
public void init(@Observes VRaptorInitialized event){ 
// send email notifying deploy 
} 
}
Serious CoC
Serious CoC
Specialize!
public class MyPathResolver { 
protected String getPrefix() { 
return "/WEB-INF/pages/"; 
} 
}
public class MyPathResolver extends DefaultPathResolver { 
// delegate constructor 
@Override 
protected String getPrefix() { 
return "/WEB-INF/pages/"; 
} 
}
@Specializes 
public class MyPathResolver extends DefaultPathResolver { 
// delegate constructor 
@Override 
protected String getPrefix() { 
return "/WEB-INF/pages/"; 
} 
}
PROGRAMMATIC 
configuration
specialize 
anything! 
(thanks to global activation)
@Decorator 
@Named @Priority 
@Qualifier @Alternative 
any CDI feature 
YOU WANT!
VRaptor 
CDI 
JavaEE
Bean 
Validation
public class Speaker { 
private String name; 
private String email; 
private int age; 
// getters and setters 
}
public class Speaker { 
@NotNull @NotEmpty 
private String name; 
@NotNull @Pattern(regexp="...") 
private String email; 
@Min(0) @Max(100) 
private int age; 
// getters and setters 
}
Bean Validation 
+ 
VRaptor
@Controller 
public class SpeakerController { 
//... 
public void add(Speaker speaker) { 
speakerDao.save(speaker); 
result.redirectTo(this).list(); 
} 
}
@Controller 
public class SpeakerController { 
//... 
public void add(@Valid Speaker speaker) { 
speakerDao.save(speaker); 
result.redirectTo(this).list(); 
} 
}
@Controller 
public class SpeakerController { 
//... 
public void add(@Valid Speaker speaker) { 
//redirect in case of validation errors 
speakerDao.save(speaker); 
result.redirectTo(this).list(); 
} 
}
import br.com.caelum.vraptor.validator.Validator; 
@Controller 
public class SpeakerController { 
@Inject private Validator validator; 
public void add(@Valid Speaker speaker) { 
validator.onErrorRedirectTo(this).add(); 
speakerDao.save(speaker); 
result.redirectTo(this).list(); 
} 
}
import br.com.caelum.validator.Validator; 
validator. 
onErrorRedirectTo(...) 
onErrorForwardTo(...) 
onErrorUsePageOf(...) 
onErrorSendBadRequest(...)
import br.com.caelum.validator.Validator; 
validator. 
onErrorRedirectTo(...) 
onErrorForwardTo(...) 
onErrorUsePageOf(...) 
onErrorSendBadRequest(...) 
check(...) 
ensure(...)
JPA
@ApplicationScoped 
public class EntityManagerProducer { 
@Inject private EntityManagerFactory emf; 
@RequestScoped @Produces 
public EntityManager produce() { 
return emf.createEntityManager(); 
@RequestScoped 
public class SpeakerDao { 
@Inject 
private EntityManager em; 
} 
} 
}
@ApplicationScoped 
public class EntityManagerProducer { 
@Inject private EntityManagerFactory emf; 
@RequestScoped @Produces 
public EntityManager produce() { 
return emf.createEntityManager(); 
@RequestScoped 
public class SpeakerDao { 
@PersistenceContext 
private EntityManager em; 
} 
} 
}
@RequestScoped 
public class SpeakerDao { 
@PersistenceContext 
private EntityManager em; 
public void save(Speaker speaker) { 
em.getTransaction().begin(); 
em.persist(speaker); 
em.getTransaction().commit(); 
} 
public List<Speaker> list() { 
return em 
.createQuery("select s from Speaker s") 
.getResultList(); 
} 
}
EJB
@RequestScoped @Stateless 
public class SpeakerDao { 
@PersistenceContext 
private EntityManager em; 
public void save(Speaker speaker) { 
em.getTransaction().begin(); 
em.persist(speaker); 
em.getTransaction().commit(); 
} 
public List<Speaker> list() { 
return em 
.createQuery("select s from Speaker s") 
.getResultList(); 
} 
}
JTA
@RequestScoped @Stateless 
public class SpeakerDao { 
@PersistenceContext 
private EntityManager em; 
@Transactional 
public void save(Speaker speaker) { 
em.getTransaction().begin(); 
em.persist(speaker); 
em.getTransaction().commit(); 
} 
public List<Speaker> list() { 
return em 
.createQuery("select s from Speaker s") 
.getResultList(); 
} 
}
JMS 
Schedulers 
JavaMail and MORE! 
any JavaEE feature 
YOU WANT!
github.com/caelum/vraptor-javaone
what about 
SERVLET CONTAINERS?
Plugins!
vraptor-jpa EntityManager injection and 
transaction support 
vraptor-hibernate Session injection and 
transaction support
vraptor-simplemail E-mail delivering 
and templating 
vraptor-quartzjob Task scheduling
and also for a 
MANAGED 
ENVIRONMENT
vraptor-actioncache Caching of controller 
actions 
vraptor-paginator JPA/Hibernate query 
pagination
vraptor-i18n Improved i18n 
vraptor-biscotti Type-safe i18n 
messages
vraptor-pannetone Compiled and type-safe 
views 
vraptor-brutauth Complex authorization 
rules
more at 
github.com/caelum/vraptor-contrib
Thank you 
github.com/caelum/vraptor4 
caelum-vraptor-en@googlegroups.com 
questions.vraptor.org 
vraptor.org

More Related Content

What's hot

Clean up your code with C#6
Clean up your code with C#6Clean up your code with C#6
Clean up your code with C#6Rui Carvalho
 
Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001Sven Ruppert
 
Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014biicode
 
DI Frameworks - hidden pearls
DI Frameworks - hidden pearlsDI Frameworks - hidden pearls
DI Frameworks - hidden pearlsSven Ruppert
 
Networking and Data Access with Eqela
Networking and Data Access with EqelaNetworking and Data Access with Eqela
Networking and Data Access with Eqelajobandesther
 
Going native with less coupling: Dependency Injection in C++
Going native with less coupling: Dependency Injection in C++Going native with less coupling: Dependency Injection in C++
Going native with less coupling: Dependency Injection in C++Daniele Pallastrelli
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 
Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)Dhaval Dalal
 
Developing Drizzle Replication Plugins
Developing Drizzle Replication PluginsDeveloping Drizzle Replication Plugins
Developing Drizzle Replication PluginsPadraig O'Sullivan
 
Leveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results AsynchrhonouslyLeveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results AsynchrhonouslyDavid Gómez García
 
Android Design Patterns
Android Design PatternsAndroid Design Patterns
Android Design PatternsGodfrey Nolan
 
My way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionMy way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionChristian Panadero
 

What's hot (20)

Android TDD
Android TDDAndroid TDD
Android TDD
 
Angular Schematics
Angular SchematicsAngular Schematics
Angular Schematics
 
Clean up your code with C#6
Clean up your code with C#6Clean up your code with C#6
Clean up your code with C#6
 
Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001
 
Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014
 
DI Frameworks - hidden pearls
DI Frameworks - hidden pearlsDI Frameworks - hidden pearls
DI Frameworks - hidden pearls
 
Networking and Data Access with Eqela
Networking and Data Access with EqelaNetworking and Data Access with Eqela
Networking and Data Access with Eqela
 
Going native with less coupling: Dependency Injection in C++
Going native with less coupling: Dependency Injection in C++Going native with less coupling: Dependency Injection in C++
Going native with less coupling: Dependency Injection in C++
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)
 
Developing Drizzle Replication Plugins
Developing Drizzle Replication PluginsDeveloping Drizzle Replication Plugins
Developing Drizzle Replication Plugins
 
Leveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results AsynchrhonouslyLeveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results Asynchrhonously
 
Core Java - Quiz Questions - Bug Hunt
Core Java - Quiz Questions - Bug HuntCore Java - Quiz Questions - Bug Hunt
Core Java - Quiz Questions - Bug Hunt
 
groovy & grails - lecture 10
groovy & grails - lecture 10groovy & grails - lecture 10
groovy & grails - lecture 10
 
Graphql, REST and Apollo
Graphql, REST and ApolloGraphql, REST and Apollo
Graphql, REST and Apollo
 
My java file
My java fileMy java file
My java file
 
Android Design Patterns
Android Design PatternsAndroid Design Patterns
Android Design Patterns
 
My way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionMy way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca edition
 
Makefiles Bioinfo
Makefiles BioinfoMakefiles Bioinfo
Makefiles Bioinfo
 
Agile Android
Agile AndroidAgile Android
Agile Android
 

Similar to VRaptor 4 - JavaOne

Introduction to cdi given at java one 2014
Introduction to cdi given at java one 2014Introduction to cdi given at java one 2014
Introduction to cdi given at java one 2014Antoine Sabot-Durand
 
1/3 : introduction to CDI - Antoine Sabot-Durand
1/3 : introduction to CDI - Antoine Sabot-Durand1/3 : introduction to CDI - Antoine Sabot-Durand
1/3 : introduction to CDI - Antoine Sabot-DurandSOAT
 
CDI e as ideias pro futuro do VRaptor
CDI e as ideias pro futuro do VRaptorCDI e as ideias pro futuro do VRaptor
CDI e as ideias pro futuro do VRaptorCaelum
 
How to Start Test-Driven Development in Legacy Code
How to Start Test-Driven Development in Legacy CodeHow to Start Test-Driven Development in Legacy Code
How to Start Test-Driven Development in Legacy CodeDaniel Wellman
 
TDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETTDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETtdc-globalcode
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentationipolevoy
 
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDBTDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDBtdc-globalcode
 
CDI do básico ao avançado
CDI do básico ao avançadoCDI do básico ao avançado
CDI do básico ao avançadoAlberto Souza
 
REST made simple with Java
REST made simple with JavaREST made simple with Java
REST made simple with Javaelliando dias
 
Padroes Projeto
Padroes ProjetoPadroes Projeto
Padroes Projetolcbj
 
The 2016 Android Developer Toolbox [NANTES]
The 2016 Android Developer Toolbox [NANTES]The 2016 Android Developer Toolbox [NANTES]
The 2016 Android Developer Toolbox [NANTES]Nilhcem
 
InspiringCon15: Bringing TYPO3 Legacy Applications into the Flow
InspiringCon15: Bringing TYPO3 Legacy Applications into the FlowInspiringCon15: Bringing TYPO3 Legacy Applications into the Flow
InspiringCon15: Bringing TYPO3 Legacy Applications into the Flowmhelmich
 
當ZK遇見Front-End
當ZK遇見Front-End當ZK遇見Front-End
當ZK遇見Front-End祁源 朱
 
Jakarta EE: The First Parts
Jakarta EE: The First PartsJakarta EE: The First Parts
Jakarta EE: The First PartsKenji HASUNUMA
 
Jakarta EE : The First Parts
Jakarta EE : The First PartsJakarta EE : The First Parts
Jakarta EE : The First PartsKenji HASUNUMA
 
The 2016 Android Developer Toolbox [MOBILIZATION]
The 2016 Android Developer Toolbox [MOBILIZATION]The 2016 Android Developer Toolbox [MOBILIZATION]
The 2016 Android Developer Toolbox [MOBILIZATION]Nilhcem
 

Similar to VRaptor 4 - JavaOne (20)

Introduction to cdi given at java one 2014
Introduction to cdi given at java one 2014Introduction to cdi given at java one 2014
Introduction to cdi given at java one 2014
 
1/3 : introduction to CDI - Antoine Sabot-Durand
1/3 : introduction to CDI - Antoine Sabot-Durand1/3 : introduction to CDI - Antoine Sabot-Durand
1/3 : introduction to CDI - Antoine Sabot-Durand
 
CDI e as ideias pro futuro do VRaptor
CDI e as ideias pro futuro do VRaptorCDI e as ideias pro futuro do VRaptor
CDI e as ideias pro futuro do VRaptor
 
Codemotion appengine
Codemotion appengineCodemotion appengine
Codemotion appengine
 
How to Start Test-Driven Development in Legacy Code
How to Start Test-Driven Development in Legacy CodeHow to Start Test-Driven Development in Legacy Code
How to Start Test-Driven Development in Legacy Code
 
TDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETTDC2016SP - Trilha .NET
TDC2016SP - Trilha .NET
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentation
 
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDBTDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
 
CDI do básico ao avançado
CDI do básico ao avançadoCDI do básico ao avançado
CDI do básico ao avançado
 
Ejb3 Dan Hinojosa
Ejb3 Dan HinojosaEjb3 Dan Hinojosa
Ejb3 Dan Hinojosa
 
REST made simple with Java
REST made simple with JavaREST made simple with Java
REST made simple with Java
 
REST made simple with Java
REST made simple with JavaREST made simple with Java
REST made simple with Java
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
Padroes Projeto
Padroes ProjetoPadroes Projeto
Padroes Projeto
 
The 2016 Android Developer Toolbox [NANTES]
The 2016 Android Developer Toolbox [NANTES]The 2016 Android Developer Toolbox [NANTES]
The 2016 Android Developer Toolbox [NANTES]
 
InspiringCon15: Bringing TYPO3 Legacy Applications into the Flow
InspiringCon15: Bringing TYPO3 Legacy Applications into the FlowInspiringCon15: Bringing TYPO3 Legacy Applications into the Flow
InspiringCon15: Bringing TYPO3 Legacy Applications into the Flow
 
當ZK遇見Front-End
當ZK遇見Front-End當ZK遇見Front-End
當ZK遇見Front-End
 
Jakarta EE: The First Parts
Jakarta EE: The First PartsJakarta EE: The First Parts
Jakarta EE: The First Parts
 
Jakarta EE : The First Parts
Jakarta EE : The First PartsJakarta EE : The First Parts
Jakarta EE : The First Parts
 
The 2016 Android Developer Toolbox [MOBILIZATION]
The 2016 Android Developer Toolbox [MOBILIZATION]The 2016 Android Developer Toolbox [MOBILIZATION]
The 2016 Android Developer Toolbox [MOBILIZATION]
 

Recently uploaded

WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 

Recently uploaded (20)

WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 

VRaptor 4 - JavaOne

  • 1. Agile Development with CDI in a Java EE World
  • 2. R. Turini Java EE Instructor VRaptor lead developer
  • 4. Java training Community Open Source!
  • 5.
  • 7. MVC web framework Action-based
  • 11. CDI
  • 14. @Controller public class SpeakerController { @Inject private SpeakerDao speakerDao; @Inject private Result result; @Get("speaker/add") public void add() {} @Post("speaker/add") public void add(Speaker speaker) { speakerDao.save(speaker); result.redirectTo(this).list(); } public void list() { result.include("speakers", speakerDao.list()); } }
  • 16. @Controller public class SpeakerController { public void add() { } }
  • 17. @Controller public class SpeakerController { speaker/add pattern: controllerName/methodName public void add() { } }
  • 18. @Controller public class SpeakerController { speaker/add pattern: controllerName/methodName public void add() { } } /WEB-INF/jsp/speaker/add.jsp pattern: /WEB-INF/jsp/controllerName/methodName.jsp
  • 19. Methods with the same name ?
  • 20. @Controller public class SpeakerController { public void add() { } public void add(Speaker speaker) { speakerDao.save(speaker); } } speaker/add
  • 22. @Controller public class SpeakerController { public void add() { } public void add(Speaker speaker) { speakerDao.save(speaker); } }
  • 23. @Controller public class SpeakerController { @Path("/speaker/form") public void add() { } @Path("/speaker/add") public void add(Speaker speaker) { speakerDao.save(speaker); } } explicitly defining the path, using: @Path("/your/custom/path")
  • 24. @Controller public class SpeakerController { @Get public void add() { } @Post public void add(Speaker speaker) { speakerDao.save(speaker); } } limit access to a controller method acording with the HTTP verb, using: @Get, @Post, @Put or @Delete
  • 25. @Controller public class SpeakerController { @Get("/speaker/form") public void add() { } @Post("/speaker/add") public void add(Speaker speaker) { speakerDao.save(speaker); } } Or both! @Get("/your/custom/path")
  • 27. @Controller public class SpeakerController { // other methods @Post("/speaker/add") public void add(Speaker speaker) { speakerDao.save(speaker); } }
  • 28. @Controller public class SpeakerController { // other methods @Post("/speaker/add") public void add(String name, int age) { Speaker speaker = new Speaker(name, age); speakerDao.save(speaker); } }
  • 29. @Controller public class SpeakerController { // other methods @Post("/speaker/add") public void add(String name, int age) { Speaker speaker = new Speaker(name, age); speakerDao.save(speaker); } } <form action="/speaker/add" method="post"> Name: <input name="name"> Age: <input name="age"> <input type="submit"> </form>
  • 30. @Controller public class SpeakerController { // other methods @Post("/speaker/add") public void add(Speaker speaker) { Speaker speaker = new Speaker(name, age); speakerDao.save(speaker); } }
  • 31. @Controller public class SpeakerController { // other methods @Post("/speaker/add") public void add(Speaker speaker) { Speaker speaker = new Speaker(name, age); speakerDao.save(speaker); <form action="/speaker/add" method="post"> Name: <input name="speaker.name"> Age: <input name="speaker.age"> <input type="submit"> </form> } }
  • 32. Name: <input name="speaker.name"> Age: <input name="speaker.age"> ?speaker.name=Chico&speaker.age=26 new Speaker("Chico", 26)
  • 33. Name: <input name="speaker.name"> ?speaker.name=Chico speaker.setName("Chico")
  • 35. @Controller public class SpeakerController { @Post("/speaker/add") public void add(Speaker speaker) { speakerDao.save(speaker); // must redirect to list method } public void list() { // include something to the view } }
  • 36. @Controller public class SpeakerController { @Post("/speaker/add") public void add(Speaker speaker) { speakerDao.save(speaker); result.redirectTo("/speaker/list"); } public void list() { // including something to the view } }
  • 37. @Controller public class SpeakerController { @Post("/speaker/add") public void add(Speaker speaker) { speakerDao.save(speaker); result.redirectTo(this).list(); } public void list() { // including something to the view } }
  • 38. DI
  • 39. @Controller public class SpeakerController { @Inject private Result result; @Post("/speaker/add") public void add(Speaker speaker) { speakerDao.save(speaker); result.redirectTo(this).list(); } public void list() { // including something to the view } }
  • 40. @Controller public class SpeakerController { @Inject private Result result; @Post("/speaker/add") public void add(Speaker speaker) { speakerDao.save(speaker); result.redirectTo(this).list(); } public void list() { // including something to the view } }
  • 42. @Controller public class SpeakerController { @Inject private Result result; @Post("/speaker/add") public void add(Speaker speaker) { speakerDao.save(speaker); result.redirectTo(this).list(); } @Get("speaker/list") public void list() { result.include("speakers", speakerDao.list()); } }
  • 43. public void list() { result.include("speakers", speakerDao.list()); } <html> <body> <ul> <c:forEach items="${speakers}" var="speaker"> <li>${speaker.name}</li> </c:forEach> </ul> </body> </html>
  • 45. public void list() { result.use(Results.json()) .from(speakerDao.list()).serialize(); } {"list":[ {"name":"Rodrigo Turini", ...}, {"name":"Chico Sokol", ...} ]}
  • 46. public void list() { result.use(Results.xml()) .from(speakerDao.list()).serialize(); <list> <speaker> <name>Rodrigo Turini</name> ... </speaker> <speaker> <name>Chico Sokol</name> ... </speaker> </list> }
  • 49. public class SpeakerDao { public void save(Speaker speaker) { //persist our speaker } public List<Speaker> list() { //return all speakers from db } }
  • 50. @RequestScoped public class SpeakerDao { public void save(Speaker speaker) { //persist our speaker Any annotated class is a CDI Bean } public List<Speaker> list() { //return all speakers from db } }
  • 51. @RequestScoped public class SpeakerDao { //... } @Controller public class SpeakerController { @Inject private SpeakerDao speakerDao; @Post("/speaker/add") public void add(Speaker speaker) { speakerDao.save(speaker); } }
  • 53. @RequestScoped public class SpeakerDao { private EntityManager em; public void save(Speaker speaker) { em.persist(speaker); } }
  • 54. @RequestScoped public class SpeakerDao { @Inject private EntityManager em; public void save(Speaker speaker) { em.persist(speaker); } }
  • 55. @RequestScoped public class SpeakerDao { @Inject private EntityManager em; public void save(Speaker speaker) { em.persist(speaker); } } EntityManager isn't a CDI bean!
  • 56. @Produces @RequestScoped public EntityManager produce() { return emf.createEntityManager(); }
  • 57. @ApplicationScoped public class EntityManagerProducer { private EntityManagerFactory emf; @PostConstruct public void init() { emf = // initializing EM factory } @Produces @RequestScoped public EntityManager produce() { return emf.createEntityManager(); } }
  • 59. @RequestScoped public class SpeakerDao { @Inject private EntityManager em; public void save(Speaker speaker) { em.getTransaction().begin(); em.persist(speaker); em.getTransaction().commit(); } }
  • 61. @InterceptorBinding @Target({METHOD,TYPE}) @Retention(RUNTIME) public @interface UsingTransaction { }
  • 62. @Interceptor @UsingTransaction @Priority(100) public class TransactionalInterceptor { @Inject private EntityManager em; @AroundInvoke public Object intercept(InvocationContext context) throws Exception { em.getTransaction().begin(); Object proceed = context.proceed(); em.getTransaction().commit(); return proceed; } }
  • 63. @RequestScoped public class SpeakerDao { @Inject private EntityManager em; public void save(Speaker speaker) { em.getTransaction().begin(); em.persist(speaker); em.getTransaction().commit(); } }
  • 64. @RequestScoped public class SpeakerDao { @Inject private EntityManager em; @UsingTransaction public void save(Speaker speaker) { em.getTransaction().begin(); em.persist(speaker); em.getTransaction().commit(); } }
  • 66.
  • 67. You can observe VRaptor events
  • 68. @ApplicationScoped public class VRaptorStartupObserver { public void init(@Observes VRaptorInitialized event){ // send email notifying deploy } }
  • 69. @ApplicationScoped public class VRaptorStartupObserver { public void init(@Observes VRaptorInitialized event){ // send email notifying deploy } }
  • 73. public class MyPathResolver { protected String getPrefix() { return "/WEB-INF/pages/"; } }
  • 74. public class MyPathResolver extends DefaultPathResolver { // delegate constructor @Override protected String getPrefix() { return "/WEB-INF/pages/"; } }
  • 75. @Specializes public class MyPathResolver extends DefaultPathResolver { // delegate constructor @Override protected String getPrefix() { return "/WEB-INF/pages/"; } }
  • 77. specialize anything! (thanks to global activation)
  • 78. @Decorator @Named @Priority @Qualifier @Alternative any CDI feature YOU WANT!
  • 81. public class Speaker { private String name; private String email; private int age; // getters and setters }
  • 82. public class Speaker { @NotNull @NotEmpty private String name; @NotNull @Pattern(regexp="...") private String email; @Min(0) @Max(100) private int age; // getters and setters }
  • 83. Bean Validation + VRaptor
  • 84. @Controller public class SpeakerController { //... public void add(Speaker speaker) { speakerDao.save(speaker); result.redirectTo(this).list(); } }
  • 85. @Controller public class SpeakerController { //... public void add(@Valid Speaker speaker) { speakerDao.save(speaker); result.redirectTo(this).list(); } }
  • 86. @Controller public class SpeakerController { //... public void add(@Valid Speaker speaker) { //redirect in case of validation errors speakerDao.save(speaker); result.redirectTo(this).list(); } }
  • 87. import br.com.caelum.vraptor.validator.Validator; @Controller public class SpeakerController { @Inject private Validator validator; public void add(@Valid Speaker speaker) { validator.onErrorRedirectTo(this).add(); speakerDao.save(speaker); result.redirectTo(this).list(); } }
  • 88. import br.com.caelum.validator.Validator; validator. onErrorRedirectTo(...) onErrorForwardTo(...) onErrorUsePageOf(...) onErrorSendBadRequest(...)
  • 89. import br.com.caelum.validator.Validator; validator. onErrorRedirectTo(...) onErrorForwardTo(...) onErrorUsePageOf(...) onErrorSendBadRequest(...) check(...) ensure(...)
  • 90. JPA
  • 91. @ApplicationScoped public class EntityManagerProducer { @Inject private EntityManagerFactory emf; @RequestScoped @Produces public EntityManager produce() { return emf.createEntityManager(); @RequestScoped public class SpeakerDao { @Inject private EntityManager em; } } }
  • 92. @ApplicationScoped public class EntityManagerProducer { @Inject private EntityManagerFactory emf; @RequestScoped @Produces public EntityManager produce() { return emf.createEntityManager(); @RequestScoped public class SpeakerDao { @PersistenceContext private EntityManager em; } } }
  • 93. @RequestScoped public class SpeakerDao { @PersistenceContext private EntityManager em; public void save(Speaker speaker) { em.getTransaction().begin(); em.persist(speaker); em.getTransaction().commit(); } public List<Speaker> list() { return em .createQuery("select s from Speaker s") .getResultList(); } }
  • 94. EJB
  • 95. @RequestScoped @Stateless public class SpeakerDao { @PersistenceContext private EntityManager em; public void save(Speaker speaker) { em.getTransaction().begin(); em.persist(speaker); em.getTransaction().commit(); } public List<Speaker> list() { return em .createQuery("select s from Speaker s") .getResultList(); } }
  • 96. JTA
  • 97. @RequestScoped @Stateless public class SpeakerDao { @PersistenceContext private EntityManager em; @Transactional public void save(Speaker speaker) { em.getTransaction().begin(); em.persist(speaker); em.getTransaction().commit(); } public List<Speaker> list() { return em .createQuery("select s from Speaker s") .getResultList(); } }
  • 98. JMS Schedulers JavaMail and MORE! any JavaEE feature YOU WANT!
  • 100. what about SERVLET CONTAINERS?
  • 102. vraptor-jpa EntityManager injection and transaction support vraptor-hibernate Session injection and transaction support
  • 103. vraptor-simplemail E-mail delivering and templating vraptor-quartzjob Task scheduling
  • 104. and also for a MANAGED ENVIRONMENT
  • 105. vraptor-actioncache Caching of controller actions vraptor-paginator JPA/Hibernate query pagination
  • 106. vraptor-i18n Improved i18n vraptor-biscotti Type-safe i18n messages
  • 107. vraptor-pannetone Compiled and type-safe views vraptor-brutauth Complex authorization rules
  • 109. Thank you github.com/caelum/vraptor4 caelum-vraptor-en@googlegroups.com questions.vraptor.org vraptor.org