109
Agile Development with CDI in a Java EE World

VRaptor 4 - JavaOne

Embed Size (px)

DESCRIPTION

VRaptor - Agile Development with CDI in a Java EE World

Citation preview

Page 1: VRaptor 4 - JavaOne

Agile Development with CDI in a Java EE World

Page 2: VRaptor 4 - JavaOne

R. TuriniJava EE Instructor

VRaptor lead developer

Page 3: VRaptor 4 - JavaOne

Chico Sokol

Page 4: VRaptor 4 - JavaOne

Java training

Open Source!Community

Page 5: VRaptor 4 - JavaOne
Page 6: VRaptor 4 - JavaOne

What is

VRaptor ?

Page 7: VRaptor 4 - JavaOne

MVCAction-based

web framework

Page 8: VRaptor 4 - JavaOne

Why

VRaptor ?

Page 9: VRaptor 4 - JavaOne

Simple Flexible

Open Source

Page 10: VRaptor 4 - JavaOne

JSR-371MVC 1.0

Page 11: VRaptor 4 - JavaOne

CDI

Page 12: VRaptor 4 - JavaOne

CDI+ JavaEE 7

Page 13: VRaptor 4 - JavaOne

VRaptorbasics

Page 14: VRaptor 4 - JavaOne

@Controllerpublic 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()); }}

Page 15: VRaptor 4 - JavaOne

SeriousCoC

Page 16: VRaptor 4 - JavaOne

@Controllerpublic class SpeakerController {

public void add() { }}

Page 17: VRaptor 4 - JavaOne

speaker/addpattern: controllerName/methodName

@Controllerpublic class SpeakerController {

public void add() { }}

Page 18: VRaptor 4 - JavaOne

speaker/addpattern: controllerName/methodName

@Controllerpublic class SpeakerController {

public void add() { }}

/WEB-INF/jsp/speaker/add.jsppattern: /WEB-INF/jsp/controllerName/methodName.jsp

Page 19: VRaptor 4 - JavaOne

Methods with the ?same name

Page 20: VRaptor 4 - JavaOne

@Controllerpublic class SpeakerController {

public void add() { }

public void add(Speaker speaker) { speakerDao.save(speaker); }}

speaker/add

Page 21: VRaptor 4 - JavaOne

ambiguityURL

Page 22: VRaptor 4 - JavaOne

@Controllerpublic class SpeakerController {

public void add() { }

public void add(Speaker speaker) { speakerDao.save(speaker); }}

Page 23: VRaptor 4 - JavaOne

@Controllerpublic 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")

Page 24: VRaptor 4 - JavaOne

@Controllerpublic 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

Page 25: VRaptor 4 - JavaOne

@Controllerpublic 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")

Page 26: VRaptor 4 - JavaOne

Parameterinjection

Page 27: VRaptor 4 - JavaOne

@Controllerpublic class SpeakerController {

// other methods

@Post("/speaker/add") public void add(Speaker speaker) { speakerDao.save(speaker); }}

Page 28: VRaptor 4 - JavaOne

@Controllerpublic class SpeakerController {

// other methods

@Post("/speaker/add") public void add(String name, int age) { Speaker speaker = new Speaker(name, age); speakerDao.save(speaker); }}

Page 29: VRaptor 4 - JavaOne

@Controllerpublic 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>

Page 30: VRaptor 4 - JavaOne

@Controllerpublic class SpeakerController {

// other methods

@Post("/speaker/add") public void add(Speaker speaker) { Speaker speaker = new Speaker(name, age); speakerDao.save(speaker); }}

Page 31: VRaptor 4 - JavaOne

<form action="/speaker/add" method="post"> Name: <input name="speaker.name"> Age: <input name="speaker.age"> <input type="submit"></form>

@Controllerpublic class SpeakerController {

// other methods

@Post("/speaker/add") public void add(Speaker speaker) { Speaker speaker = new Speaker(name, age); speakerDao.save(speaker); }}

Page 32: VRaptor 4 - JavaOne

Name: <input name="speaker.name"> Age: <input name="speaker.age">

new Speaker("Chico", 26)

?speaker.name=Chico&speaker.age=26

Page 33: VRaptor 4 - JavaOne

Name: <input name="speaker.name">

speaker.setName("Chico")

?speaker.name=Chico

Page 34: VRaptor 4 - JavaOne

Redirectingto another logic

Page 35: VRaptor 4 - JavaOne

@Controllerpublic 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 }}

Page 36: VRaptor 4 - JavaOne

@Controllerpublic 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 }}

Page 37: VRaptor 4 - JavaOne

@Controllerpublic 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 }}

Page 38: VRaptor 4 - JavaOne

DI

Page 39: VRaptor 4 - JavaOne

@Controllerpublic 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 }}

Page 40: VRaptor 4 - JavaOne

@Controllerpublic 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 }}

Page 41: VRaptor 4 - JavaOne

including

attributes

Page 42: VRaptor 4 - JavaOne

@Controllerpublic 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()); }}

Page 43: VRaptor 4 - JavaOne

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>

Page 44: VRaptor 4 - JavaOne

SERVICES ?what about

Page 45: VRaptor 4 - JavaOne

public void list() { result.use(Results.json()) .from(speakerDao.list()).serialize();}

{"list":[

{"name":"Rodrigo Turini", ...},

{"name":"Chico Sokol", ...}

]}

Page 46: VRaptor 4 - JavaOne

<list>

<speaker>

<name>Rodrigo Turini</name> ...

</speaker>

<speaker>

<name>Chico Sokol</name> ...

</speaker>

</list>

public void list() { result.use(Results.xml()) .from(speakerDao.list()).serialize();}

Page 47: VRaptor 4 - JavaOne

Taking advantage of

CDI

Page 48: VRaptor 4 - JavaOne

Inject

ANYbean

Page 49: VRaptor 4 - JavaOne

public class SpeakerDao {

public void save(Speaker speaker) { //persist our speaker }

public List<Speaker> list() { //return all speakers from db }}

Page 50: VRaptor 4 - JavaOne

Any annotated class is a CDI Bean

@RequestScopedpublic class SpeakerDao {

public void save(Speaker speaker) { //persist our speaker }

public List<Speaker> list() { //return all speakers from db }}

Page 51: VRaptor 4 - JavaOne

@RequestScopedpublic class SpeakerDao { //...}

@Controllerpublic class SpeakerController {

@Inject private SpeakerDao speakerDao;

@Post("/speaker/add") public void add(Speaker speaker) { speakerDao.save(speaker); }}

Page 52: VRaptor 4 - JavaOne

Inject

third partyclasses

Page 53: VRaptor 4 - JavaOne

@RequestScopedpublic class SpeakerDao {

private EntityManager em;

public void save(Speaker speaker) { em.persist(speaker); }}

Page 54: VRaptor 4 - JavaOne

@RequestScopedpublic class SpeakerDao { @Inject private EntityManager em;

public void save(Speaker speaker) { em.persist(speaker); }}

Page 55: VRaptor 4 - JavaOne

@RequestScopedpublic class SpeakerDao { @Inject private EntityManager em;

public void save(Speaker speaker) { em.persist(speaker); }}

EntityManager isn't a CDI bean!

Page 56: VRaptor 4 - JavaOne

@Produces @RequestScoped public EntityManager produce() { return emf.createEntityManager(); }

Page 57: VRaptor 4 - JavaOne

@ApplicationScopedpublic class EntityManagerProducer {

private EntityManagerFactory emf;

@PostConstruct public void init() { emf = // initializing EM factory }

@Produces @RequestScoped public EntityManager produce() { return emf.createEntityManager(); }}

Page 58: VRaptor 4 - JavaOne

what about

TRANSACTIONS ?

Page 59: VRaptor 4 - JavaOne

@RequestScopedpublic class SpeakerDao {

@Inject private EntityManager em;

public void save(Speaker speaker) { em.getTransaction().begin(); em.persist(speaker); em.getTransaction().commit();

}}

Page 60: VRaptor 4 - JavaOne

CDI’s

Interceptor

Page 61: VRaptor 4 - JavaOne

@InterceptorBinding@Target({METHOD,TYPE})@Retention(RUNTIME)public @interface UsingTransaction {}

Page 62: VRaptor 4 - JavaOne

@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; }}

Page 63: VRaptor 4 - JavaOne

@RequestScopedpublic class SpeakerDao {

@Inject private EntityManager em;

public void save(Speaker speaker) { em.getTransaction().begin(); em.persist(speaker); em.getTransaction().commit();

}}

Page 64: VRaptor 4 - JavaOne

@RequestScopedpublic class SpeakerDao {

@Inject private EntityManager em;

@UsingTransaction public void save(Speaker speaker) { em.getTransaction().begin(); em.persist(speaker); em.getTransaction().commit();

}}

Page 65: VRaptor 4 - JavaOne

CDI’s

Events

Page 66: VRaptor 4 - JavaOne
Page 67: VRaptor 4 - JavaOne

VRaptorYou can observe

events

Page 68: VRaptor 4 - JavaOne

@ApplicationScopedpublic class VRaptorStartupObserver { public void init(@Observes VRaptorInitialized event){

// send email notifying deploy

}}

Page 69: VRaptor 4 - JavaOne

@ApplicationScopedpublic class VRaptorStartupObserver { public void init(@Observes VRaptorInitialized event){

// send email notifying deploy

}}

Page 70: VRaptor 4 - JavaOne

Serious

CoC

Page 71: VRaptor 4 - JavaOne

Serious

CoC

Page 72: VRaptor 4 - JavaOne

Specialize!

Page 73: VRaptor 4 - JavaOne

public class MyPathResolver {

protected String getPrefix() { return "/WEB-INF/pages/"; }}

Page 74: VRaptor 4 - JavaOne

public class MyPathResolver extends DefaultPathResolver {

// delegate constructor @Override protected String getPrefix() { return "/WEB-INF/pages/"; }}

Page 75: VRaptor 4 - JavaOne

@Specializespublic class MyPathResolver extends DefaultPathResolver {

// delegate constructor @Override protected String getPrefix() { return "/WEB-INF/pages/"; }}

Page 76: VRaptor 4 - JavaOne

PROGRAMMATICconfiguration

Page 77: VRaptor 4 - JavaOne

anything!(thanks to global activation)

specialize

Page 78: VRaptor 4 - JavaOne

@Decorator

@Alternative@Qualifier

@Named @Priority

any CDI feature

YOU WANT!

Page 79: VRaptor 4 - JavaOne

VRaptor

CDI

JavaEE

Page 80: VRaptor 4 - JavaOne

BeanValidation

Page 81: VRaptor 4 - JavaOne

public class Speaker {

private String name;

private String email;

private int age;

// getters and setters}

Page 82: VRaptor 4 - JavaOne

public class Speaker {

@NotNull @NotEmpty private String name;

@NotNull @Pattern(regexp="...") private String email;

@Min(0) @Max(100) private int age;

// getters and setters}

Page 83: VRaptor 4 - JavaOne

Bean Validation

VRaptor+

Page 84: VRaptor 4 - JavaOne

@Controllerpublic class SpeakerController {

//...

public void add(Speaker speaker) { speakerDao.save(speaker); result.redirectTo(this).list(); }}

Page 85: VRaptor 4 - JavaOne

@Controllerpublic class SpeakerController {

//...

public void add(@Valid Speaker speaker) { speakerDao.save(speaker); result.redirectTo(this).list(); }}

Page 86: VRaptor 4 - JavaOne

@Controllerpublic class SpeakerController {

//...

public void add(@Valid Speaker speaker) { //redirect in case of validation errors speakerDao.save(speaker); result.redirectTo(this).list(); }}

Page 87: VRaptor 4 - JavaOne

import br.com.caelum.vraptor.validator.Validator;

@Controllerpublic class SpeakerController {

@Inject private Validator validator;

public void add(@Valid Speaker speaker) { validator.onErrorRedirectTo(this).add(); speakerDao.save(speaker); result.redirectTo(this).list(); }}

Page 88: VRaptor 4 - JavaOne

import br.com.caelum.validator.Validator;

validator.

onErrorRedirectTo(...)

onErrorForwardTo(...)

onErrorUsePageOf(...)

onErrorSendBadRequest(...)

Page 89: VRaptor 4 - JavaOne

import br.com.caelum.validator.Validator;

validator.

onErrorRedirectTo(...)

onErrorForwardTo(...)

onErrorUsePageOf(...)

onErrorSendBadRequest(...)

check(...)

ensure(...)

Page 90: VRaptor 4 - JavaOne

JPA

Page 91: VRaptor 4 - JavaOne

@RequestScopedpublic class SpeakerDao {

@Inject private EntityManager em;

}

@ApplicationScopedpublic class EntityManagerProducer {

@Inject private EntityManagerFactory emf;

@RequestScoped @Produces public EntityManager produce() { return emf.createEntityManager(); }

}

Page 92: VRaptor 4 - JavaOne

@RequestScopedpublic class SpeakerDao {

@PersistenceContext private EntityManager em;

}

@ApplicationScopedpublic class EntityManagerProducer {

@Inject private EntityManagerFactory emf;

@RequestScoped @Produces public EntityManager produce() { return emf.createEntityManager(); }}

Page 93: VRaptor 4 - JavaOne

@RequestScopedpublic 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(); }}

Page 94: VRaptor 4 - JavaOne

EJB

Page 95: VRaptor 4 - JavaOne

@RequestScoped @Statelesspublic 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(); }}

Page 96: VRaptor 4 - JavaOne

JTA

Page 97: VRaptor 4 - JavaOne

@RequestScoped @Statelesspublic 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(); }}

Page 98: VRaptor 4 - JavaOne

JMS

and MORE!JavaMail

Schedulers

any JavaEE feature

YOU WANT!

Page 100: VRaptor 4 - JavaOne

what about

SERVLET ?CONTAINERS

Page 101: VRaptor 4 - JavaOne

Plugins!

Page 102: VRaptor 4 - JavaOne

vraptor-jpa EntityManager injection and transaction support

vraptor-hibernate Session injection and transaction support

Page 103: VRaptor 4 - JavaOne

vraptor-simplemail E-mail deliveringand templating

vraptor-quartzjob Task scheduling

Page 104: VRaptor 4 - JavaOne

and also for a

MANAGEDENVIRONMENT

Page 105: VRaptor 4 - JavaOne

vraptor-actioncache Caching of controller actions

vraptor-paginator JPA/Hibernate querypagination

Page 106: VRaptor 4 - JavaOne

vraptor-i18n Improved i18n

vraptor-biscotti Type-safe i18nmessages

Page 107: VRaptor 4 - JavaOne

vraptor-pannetone Compiled and type-safeviews

vraptor-brutauth Complex authorizationrules