Top Banner
Apache Wicket and Java EE sitting in a tree Martijn Dashorst topicus onderwijs APACHE WICKET
263
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Apache Wicket and Java EE sitting in a tree

Apache Wicketand Java EE sitting in a tree

Martijn Dashorsttopicus onderwijs

APACHE WICKET

Page 2: Apache Wicket and Java EE sitting in a tree

Wicket and Java EE

Page 3: Apache Wicket and Java EE sitting in a tree

servlet 3

JSF 2

EJB 3.1

JPA 2

JSP

CDI

JTA

Bean Validation

JAX-WS

JAX-RPC

JAXR

SAAJ

JAX-RS

JAXB

JMS

JAAS

JASPIC

JACC

JCA

Java Mail

JSR 88

JSR 77

RMI

JNDI

Java EEweb profile

Page 4: Apache Wicket and Java EE sitting in a tree

s/[JSF|JSP]/Wicket/🌍Wicket's mission statement from 2004

Page 5: Apache Wicket and Java EE sitting in a tree

servlet 3

JSF 2

EJB 3.1

JPA 2

JSP

CDI

JTA

Bean Validation

JAX-WS

JAX-RPC

JAXR

SAAJ

JAX-RS

JAXB

JMS

JAAS

JASPIC

JACC

JCA

Java Mail

JSR 88

JSR 77

RMI

JNDI

Java EEweb profile

Page 6: Apache Wicket and Java EE sitting in a tree

servlet 3

JSF 2

EJB 3.1

JPA 2

JSP

CDI

JTA

Bean Validation

JAX-WS

JAX-RPC

JAXR

SAAJ

JAX-RS

JAXB

JMS

JAAS

JASPIC

JACC

JCA

Java Mail

JSR 88

JSR 77

RMI

JNDI

Java EEweb profile

Arquillian

Page 7: Apache Wicket and Java EE sitting in a tree

What is Wicket?

Page 8: Apache Wicket and Java EE sitting in a tree

wicket |ˈwɪkɪt|noun 1 Cricket each of the sets of three stumps with two bails across the top at either end of the pitch, defended by a batsman. • the prepared strip of ground between two sets of stumps. when they inspected the wicket, they found it being rolled by some prisoners. • the dismissal of a batsman; each of ten dismissals regarded as marking a division of a side's innings: Darlington won by four wickets. 2 (also wicket door or wicket gate)a small door or gate, especially one beside or in a larger one. • N. Amer. an opening in a door or wall, often fitted with glass or a grille and used for selling tickets or a similar purpose. 3 N. Amer. a croquet hoop. PHRASES at the wicket Cricket 1 batting: the batsman remained at the wicket. 2 by the wicketkeeper: he was caught at the wicket chasing a wide one. keep wicket Cricket be a wicketkeeper. lose a wicket Cricket (of the batting side) have a batsman dismissed. the tourists lost their last seven wickets for 94. a sticky wicket Cricket a pitch that has been drying after rain and is difficult to bat on. • informal a tricky or awkward situation: I might be on a sticky wicket if I used that line. over the wicket Cricket (referring to which side of the wicket a bowler runs when bowling) to the left of the wicket if a right-handed bowler and the right of the wicket if a left-handed bowler. round the wicket Cricket (referring to which side of the wicket a bowler runs when bowling) to the right of the wicket if a right-handed bowler and the left of the wicket if a left-handed bowler. take a wicket Cricket (of a bowler or a fielding side) dismiss a batsman. ORIGIN Middle English (in the sense ‘small door or grille’): from Anglo-Norman French and Old Northern French wiket; origin uncertain, usually referred to the Germanic root of Old Norse vīkja ‘to turn, move’. Cricket senses date from the late 17th cent.

Page 9: Apache Wicket and Java EE sitting in a tree

wicket |ˈwɪkɪt|noun 1 a component oriented, open source, Java web application framework

Page 10: Apache Wicket and Java EE sitting in a tree

components everywhere

Page 11: Apache Wicket and Java EE sitting in a tree

components everywhere

Page 12: Apache Wicket and Java EE sitting in a tree

components everywhere

Page 13: Apache Wicket and Java EE sitting in a tree

Injection (EJB, CDI)

Conversations (CDI)

JPA

Bean validation

Arquillian

Page 14: Apache Wicket and Java EE sitting in a tree

Cheese StoreExample

Page 15: Apache Wicket and Java EE sitting in a tree
Page 16: Apache Wicket and Java EE sitting in a tree
Page 17: Apache Wicket and Java EE sitting in a tree

1. Setup project

2. Add 'domain layer'

3. Add components

First steps

Page 18: Apache Wicket and Java EE sitting in a tree

1. setup the project

Page 19: Apache Wicket and Java EE sitting in a tree
Page 20: Apache Wicket and Java EE sitting in a tree
Page 21: Apache Wicket and Java EE sitting in a tree
Page 22: Apache Wicket and Java EE sitting in a tree
Page 23: Apache Wicket and Java EE sitting in a tree
Page 24: Apache Wicket and Java EE sitting in a tree
Page 25: Apache Wicket and Java EE sitting in a tree
Page 26: Apache Wicket and Java EE sitting in a tree
Page 27: Apache Wicket and Java EE sitting in a tree

Remove unnecessary files

Page 28: Apache Wicket and Java EE sitting in a tree

Rename package to

'com.cheesr.web'

Page 29: Apache Wicket and Java EE sitting in a tree
Page 30: Apache Wicket and Java EE sitting in a tree
Page 31: Apache Wicket and Java EE sitting in a tree
Page 32: Apache Wicket and Java EE sitting in a tree

package com.cheesr.web;

import org.apache.wicket.markup.html.WebPage;

public class Index extends WebPage { public Index() { } }

Page 33: Apache Wicket and Java EE sitting in a tree

package com.cheesr.web;

import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.protocol.http.WebApplica

public class WicketApplication extends WebApplica @Override public Class<? extends WebPage> getHomePage() { return Index.class; }

@Override public void init() { super.init(); } }

Page 34: Apache Wicket and Java EE sitting in a tree
Page 35: Apache Wicket and Java EE sitting in a tree
Page 36: Apache Wicket and Java EE sitting in a tree

2. Add 'domain model'

Page 37: Apache Wicket and Java EE sitting in a tree

entities

Page 38: Apache Wicket and Java EE sitting in a tree

package com.cheesr.dao;

public class CheeseDao { }

Page 39: Apache Wicket and Java EE sitting in a tree

package com.cheesr.dao;

public class CheeseDao { public List<Cheese> getCheeses() { } }

Page 40: Apache Wicket and Java EE sitting in a tree

package com.cheesr.dao; /*...*/ public class CheeseDao { public List<Cheese> getCheeses() { return asList(); } }

Page 41: Apache Wicket and Java EE sitting in a tree

package com.cheesr.dao; /*...*/ public class CheeseDao { public List<Cheese> getCheeses() { return asList( new Cheese()); } }

Page 42: Apache Wicket and Java EE sitting in a tree

package com.cheesr.dao; /*...*/ public class CheeseDao { public List<Cheese> getCheeses() { return asList( new Cheese( "Gouda", "Named after the Dutch town of Gouda, j", 1.99)); } }

Page 43: Apache Wicket and Java EE sitting in a tree

package com.cheesr.dao; /*...*/ public class CheeseDao { public List<Cheese> getCheeses() { return asList( new Cheese( "Gouda", "Named after the Dutch town of Gouda, j", 1.99), new Cheese( "Edam", "This is a pressed, semi-hard to hard c", 2.99)); } }

Page 44: Apache Wicket and Java EE sitting in a tree

package com.cheesr.dao; /*...*/ public class CheeseDao { public List<Cheese> getCheeses() { return asList( new Cheese( "Gouda", "Named after the Dutch town of Gouda, j", 1.99), new Cheese( "Edam", "This is a pressed, semi-hard to hard c", 2.99), new Cheese( "Camembert", "A very famous French cheese, Camembert", 3.99)); } }

Page 45: Apache Wicket and Java EE sitting in a tree

package com.cheesr.dao;

public class OrderDao { }

Page 46: Apache Wicket and Java EE sitting in a tree

package com.cheesr.dao;

public class OrderDao { public void save(Order order) { } }

Page 47: Apache Wicket and Java EE sitting in a tree

package com.cheesr.dao;

public class OrderDao { private List<Order> orders = new ArrayList<>();

public void save(Order order) { } }

Page 48: Apache Wicket and Java EE sitting in a tree

package com.cheesr.dao;

public class OrderDao { private List<Order> orders = new ArrayList<>();

public void save(Order order) { orders.add(order); } }

Page 49: Apache Wicket and Java EE sitting in a tree

package com.cheesr.dao;

public class OrderDao { private List<Order> orders = new ArrayList<>();

public void save(Order order) { orders.add(order); }

public List<Order> list() { } }

Page 50: Apache Wicket and Java EE sitting in a tree

package com.cheesr.dao;

public class OrderDao { private List<Order> orders = new ArrayList<>();

public void save(Order order) { orders.add(order); }

public List<Order> list() { return Collections.unmodifiableList(orders); } }

Page 51: Apache Wicket and Java EE sitting in a tree

3. Add components

Page 52: Apache Wicket and Java EE sitting in a tree
Page 53: Apache Wicket and Java EE sitting in a tree

<div class="cheese"> <h3>Gouda</h3> <p>Named after the Dutch town of Gouda, just ou <p> <span>$1.99</span> <a href="#">Add to cart</a> </p> </div>

Page 54: Apache Wicket and Java EE sitting in a tree

<div wicket:id="cheese" class="cheese"> <h3 wicket:id="name">Gouda</h3> <p wicket:id="description">Named after the Dutc <p> €<span wicket:id="price">1.99</span> <a href="#">Add to cart</a> </p> </div>

Page 55: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { public Index() { } }

Page 56: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao();

public Index() { } }

Page 57: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao();

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses(); } }

Page 58: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao();

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses(); add(new ListView<Cheese>("cheese", cheeses) { }); } }

Page 59: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao();

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses(); add(new ListView<Cheese>("cheese", cheeses) { @Override protected void populateItem(ListItem<Cheese> item) { } }); } }

Page 60: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao();

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses(); add(new ListView<Cheese>("cheese", cheeses) { @Override protected void populateItem(ListItem<Cheese> item) { Cheese c = item.getModelObject(); item.add(new Label("name", c.getName())); item.add(new Label("description", c.getDescriptio item.add(new Label("price", c.getPrice())); } }); } }

Page 61: Apache Wicket and Java EE sitting in a tree
Page 62: Apache Wicket and Java EE sitting in a tree

<h3>Your Selection</h3> <table> <tbody> <tr> <td>Gouda</td> <td>€<span>1.99</span></td> <td><a href="#">remove</a></td> </tr> </tbody> <tfoot> <tr class="total"> <th>Total</th> <td>$1.99</td> <td>&nbsp;</td> </tr> </tfoot> </table>

Page 63: Apache Wicket and Java EE sitting in a tree

<h3>Your Selection</h3> <table> <tbody> <tr wicket:id="item"> <td wicket:id="name">Gouda</td> <td>€<span wicket:id="price">1.99</span></td> <td><a href="#">remove</a></td> </tr> </tbody> <tfoot> <tr class="total"> <th>Total</th> <td>$1.99</td> <td>&nbsp;</td> </tr> </tfoot> </table>

Page 64: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao();

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses();

add(new ListView<Cheese>("cheese", cheeses) {…}); } }

Page 65: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao(); private Cart cart = new Cart();

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses();

add(new ListView<Cheese>("cheese", cheeses) {…}); } }

Page 66: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao(); private Cart cart = new Cart();

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses();

add(new ListView<Cheese>("cheese", cheeses) {…}); add(new ListView<Cheese>("item", cart.getItems()) { }); } }

Page 67: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao(); private Cart cart = new Cart();

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses();

add(new ListView<Cheese>("cheese", cheeses) {…}); add(new ListView<Cheese>("item", cart.getItems()) { @Override protected void populateItem(ListItem<Cheese> item) { } }); } }

Page 68: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao(); private Cart cart = new Cart();

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses();

add(new ListView<Cheese>("cheese", cheeses) {…}); add(new ListView<Cheese>("item", cart.getItems()) { @Override protected void populateItem(ListItem<Cheese> item) { Cheese c = item.getModelObject(); } }); } }

Page 69: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao(); private Cart cart = new Cart();

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses();

add(new ListView<Cheese>("cheese", cheeses) {…}); add(new ListView<Cheese>("item", cart.getItems()) { @Override protected void populateItem(ListItem<Cheese> item) { Cheese c = item.getModelObject(); item.add(new Label("name", c.getName())); item.add(new Label("price", c.getPrice())); } }); } }

Page 70: Apache Wicket and Java EE sitting in a tree
Page 71: Apache Wicket and Java EE sitting in a tree

<div wicket:id="cheese" class="cheese"> <h3 wicket:id="name">Gouda</h3> <p wicket:id="description">Named after the Dutc <p> €<span wicket:id="price">1.99</span> <a href="#">Add to cart</a> </p> </div>

Page 72: Apache Wicket and Java EE sitting in a tree

<div wicket:id="cheese" class="cheese"> <h3 wicket:id="name">Gouda</h3> <p wicket:id="description">Named after the Dutc <p> €<span wicket:id="price">1.99</span> <a wicket:id="price" href="#">Add to cart</a> </p> </div>

Page 73: Apache Wicket and Java EE sitting in a tree

add(new ListView<Cheese>("cheese", cheeses) { @Override protected void populateItem(ListItem<Cheese> item) { Cheese c = item.getModelObject(); item.add(new Label("name", c.getName())); item.add(new Label("description", c.getDescription())) item.add(new Label("price", c.getPrice())); } });

Page 74: Apache Wicket and Java EE sitting in a tree

add(new ListView<Cheese>("cheese", cheeses) { @Override protected void populateItem(ListItem<Cheese> item) { Cheese c = item.getModelObject(); item.add(new Label("name", c.getName())); item.add(new Label("description", c.getDescription())) item.add(new Label("price", c.getPrice())); item.add(new Link<Cheese>("price", item.getModel())); } });

Page 75: Apache Wicket and Java EE sitting in a tree

add(new ListView<Cheese>("cheese", cheeses) { @Override protected void populateItem(ListItem<Cheese> item) { Cheese c = item.getModelObject(); item.add(new Label("name", c.getName())); item.add(new Label("description", c.getDescription())) item.add(new Label("price", c.getPrice())); item.add(new Link<Cheese>("price", item.getModel()) { }); } });

Page 76: Apache Wicket and Java EE sitting in a tree

add(new ListView<Cheese>("cheese", cheeses) { @Override protected void populateItem(ListItem<Cheese> item) { Cheese c = item.getModelObject(); item.add(new Label("name", c.getName())); item.add(new Label("description", c.getDescription())) item.add(new Label("price", c.getPrice())); item.add(new Link<Cheese>("price", item.getModel()) { @Override public void onClick() { } }); } });

Page 77: Apache Wicket and Java EE sitting in a tree

add(new ListView<Cheese>("cheese", cheeses) { @Override protected void populateItem(ListItem<Cheese> item) { Cheese c = item.getModelObject(); item.add(new Label("name", c.getName())); item.add(new Label("description", c.getDescription())) item.add(new Label("price", c.getPrice())); item.add(new Link<Cheese>("price", item.getModel()) { @Override public void onClick() { Cheese cheese = getModelObject(); } }); } });

Page 78: Apache Wicket and Java EE sitting in a tree

add(new ListView<Cheese>("cheese", cheeses) { @Override protected void populateItem(ListItem<Cheese> item) { Cheese c = item.getModelObject(); item.add(new Label("name", c.getName())); item.add(new Label("description", c.getDescription())) item.add(new Label("price", c.getPrice())); item.add(new Link<Cheese>("price", item.getModel()) { @Override public void onClick() { Cheese cheese = getModelObject(); cart.getItems().add(cheese); } }); } });

Page 79: Apache Wicket and Java EE sitting in a tree

Injection (EJB, CDI)

Conversations (CDI)

JPA

Bean validation

Testing with Arquillian

Page 80: Apache Wicket and Java EE sitting in a tree

Using EJBs

Page 81: Apache Wicket and Java EE sitting in a tree

Add EJB dependencies to project

Make DAOs EJBs

Inject DAOs

Steps

Page 82: Apache Wicket and Java EE sitting in a tree

<dependencies> <!-- EJB DEPENDENCIES --> <dependency> <groupId>org.jboss.spec.javax.ejb</groupId> <artifactId>jboss-ejb-api_3.2_spec</artifactId> <scope>provided</scope> </dependency> … </dependencies>

Page 83: Apache Wicket and Java EE sitting in a tree

Add EJB dependencies to project

Make DAOs EJBs

Inject DAOs

Steps

Page 84: Apache Wicket and Java EE sitting in a tree

public class CheeseDao { public List<Cheese> getCheeses() {…} }

public class OrderDao { public void save(Order order) {…} public List<Order> list() {…} }

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao();

public Index() {…} }

Page 85: Apache Wicket and Java EE sitting in a tree

public class CheeseDao { public List<Cheese> getCheeses() {…} }

public class OrderDao { public void save(Order order) {…} public List<Order> list() {…} }

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao();

public Index() {…} }

Page 86: Apache Wicket and Java EE sitting in a tree

@Stateless public class CheeseDao { public List<Cheese> getCheeses() {…} }

public class OrderDao { public void save(Order order) {…}

public List<Order> list() {…} }

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao();

public Index() {…} }

Page 87: Apache Wicket and Java EE sitting in a tree

@Stateless public class CheeseDao { public List<Cheese> getCheeses() {…} }

@Stateless public class OrderDao { public void save(Order order) {…}

public List<Order> list() {…} }

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao();

public Index() {…} }

Page 88: Apache Wicket and Java EE sitting in a tree

@Stateless public class CheeseDao { public List<Cheese> getCheeses() {…} }

@Stateless public class OrderDao { public void save(Order order) {…}

public List<Order> list() {…} }

public class Index extends WebPage { private CheeseDao cheeseDao;

public Index() {…} }

Page 89: Apache Wicket and Java EE sitting in a tree

Add EJB dependencies to project

Make DAOs EJBs

Inject DAOs

Steps

Page 90: Apache Wicket and Java EE sitting in a tree

@Stateless public class CheeseDao { public List<Cheese> getCheeses() {…} }

@Stateless public class OrderDao { public void save(Order order) {…}

public List<Order> list() {…} }

public class Index extends WebPage { @EJB private CheeseDao cheeseDao;

public Index() {…} }

Page 91: Apache Wicket and Java EE sitting in a tree

21:20:55,305 Processing weld deployment cheesr.war 21:20:55,313 JNDI bindings for session bean named CheeseDao in deployment unit deployment "cheesr.war" are as follows:

java:global/cheesr/CheeseDao!com.cheesr.dao.CheeseDao java:app/cheesr/CheeseDao!com.cheesr.dao.CheeseDao java:module/CheeseDao!com.cheesr.dao.CheeseDao java:global/cheesr/CheeseDao java:app/cheesr/CheeseDao java:module/CheeseDao

21:20:55,335 Starting Services for CDI deployment: cheesr.war 21:20:55,340 Starting weld service for deployment cheesr.war

Page 92: Apache Wicket and Java EE sitting in a tree
Page 93: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { @EJB private CheeseDao cheeseDao;

private Cart cart = new Cart();

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses();

add(new ListView<Cheese>("cheese", cheeses) {…}); add(new ListView<Cheese>("item", cart.getItems()) {…}) } }

Page 94: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { @EJB private CheeseDao cheeseDao;

private Cart cart = new Cart();

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses();

add(new ListView<Cheese>("cheese", cheeses) {…}); add(new ListView<Cheese>("item", cart.getItems()) {…}) } }

Page 95: Apache Wicket and Java EE sitting in a tree

Wicket is unmanaged, container doesn't know about Pages, Components, etc.

Page 96: Apache Wicket and Java EE sitting in a tree
Page 97: Apache Wicket and Java EE sitting in a tree

<dependencies> <!-- EJB DEPENDENCIES --> <dependency> <groupId>org.jboss.spec.javax.ejb</groupId> <artifactId>jboss-ejb-api_3.2_spec</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.wicketstuff</groupId> <artifactId>wicketstuff-javaee-inject</artifactId> <version>6.17.0</version> </dependency> </dependencies>

Page 98: Apache Wicket and Java EE sitting in a tree

public class WicketApplication extends WebApplication { @Override public Class< ? extends WebPage> getHomePage() { return Index.class; }

@Override public void init() { super.init(); } }

Page 99: Apache Wicket and Java EE sitting in a tree

public class WicketApplication extends WebApplication { @Override public Class< ? extends WebPage> getHomePage() { return Index.class; }

@Override public void init() { super.init();

getComponentInstantiationListeners() .add(new JavaEEComponentInjector(this)); } }

Page 100: Apache Wicket and Java EE sitting in a tree
Page 101: Apache Wicket and Java EE sitting in a tree

• add EJB dependency and wicketstuff-javaee-inject dependency

• make DAOs EJBs

• configure component instantiation listener

• now you can use @EJB injection

Page 102: Apache Wicket and Java EE sitting in a tree

Using CDI for injection

Page 103: Apache Wicket and Java EE sitting in a tree

<dependencies> <!-- CDI DEPENDENCIES --> <dependency> <groupId>javax.enterprise</groupId> <artifactId>cdi-api</artifactId> </dependency> <dependency> <groupId>org.apache.wicket</groupId> <artifactId>wicket-cdi-1.1</artifactId> <version>6.18.0</version> </dependency> </dependencies>

Page 104: Apache Wicket and Java EE sitting in a tree

public class WicketApplication extends WebApplication { @Override public void init() { super.init(); } }

Page 105: Apache Wicket and Java EE sitting in a tree

public class WicketApplication extends WebApplication { @Override public void init() { super.init();

CdiConfiguration cdiConfiguration = new CdiConfiguration(); cdiConfiguration.configure(this); } }

Page 106: Apache Wicket and Java EE sitting in a tree

@ApplicationScoped public class MessageOfTheDay { public String getMessage() { return "What happens to the hole when the cheese is go } }

Page 107: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { @EJB private CheeseDao cheeseDao;

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses();

add(new ListView<Cheese>("cheese", cheeses) {…}); add(new ListView<Cheese>("item", cart.getItems()) {…}) } }

Page 108: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { @EJB private CheeseDao cheeseDao;

@Inject private MessageOfTheDay message;

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses();

add(new ListView<Cheese>("cheese", cheeses) {…}); add(new ListView<Cheese>("item", cart.getItems()) {…}) } }

Page 109: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { @EJB private CheeseDao cheeseDao;

@Inject private MessageOfTheDay message;

public Index() { add(new Label("message", message.getMessage()));

List<Cheese> cheeses = cheeseDao.getCheeses();

add(new ListView<Cheese>("cheese", cheeses) {…}); add(new ListView<Cheese>("item", cart.getItems()) {…}) } }

Page 110: Apache Wicket and Java EE sitting in a tree
Page 111: Apache Wicket and Java EE sitting in a tree

Injecting in non-managed objects

Page 112: Apache Wicket and Java EE sitting in a tree

public class MessageModel extends LoadableDetachableModel<String> { @Inject private MessageOfTheDay messages;

@Override protected String load() { return messages.getMessage(); } }

Page 113: Apache Wicket and Java EE sitting in a tree

Caused by: java.lang.NullPointerException at com.cheesr.web.MessageModel.load(MessageModel.java:15) [:] at com.cheesr.web.MessageModel.load(MessageModel.java:1) [:] at org.apache.wicket.model.LoadableDetachableModel.getObject( at org.apache.wicket.Component.getDefaultModelObject(Componen ... 55 more

Page 114: Apache Wicket and Java EE sitting in a tree

public class MessageModel extends LoadableDetachableModel<String> { @Inject private MessageOfTheDay messages;

@Override protected String load() { return messages.getMessage(); } }

Page 115: Apache Wicket and Java EE sitting in a tree

public class MessageModel extends LoadableDetachableModel<String> { @Inject private MessageOfTheDay messages;

public MessageModel() { NonContextual.of(MessageModel.class).inject(this); }

@Override protected String load() { return messages.getMessage(); } }

Page 116: Apache Wicket and Java EE sitting in a tree

• Add wicket-cdi-1.1 and javax.cdi-api

• Configure Wicket's CdiConfiguration

• Use @Inject injection

• Use NonContextual in non-managed objects

Page 117: Apache Wicket and Java EE sitting in a tree

Injection (EJB, CDI)

Conversations (CDI)

JPA

Bean validation

Testing with Arquillian

Page 118: Apache Wicket and Java EE sitting in a tree

4. Navigate to Checkout

5. Implement Checkout

6. Make Cart Conversation Scoped

Next steps

Page 119: Apache Wicket and Java EE sitting in a tree

4. navigate to checkout

Page 120: Apache Wicket and Java EE sitting in a tree
Page 121: Apache Wicket and Java EE sitting in a tree
Page 122: Apache Wicket and Java EE sitting in a tree
Page 123: Apache Wicket and Java EE sitting in a tree

<div id="cart"> <h3>Your Selection</h3> <table> <tbody>…</tbody> <tfoot>…</tfoot> </table> <input type="button" value="Check out" /> </div>

Page 124: Apache Wicket and Java EE sitting in a tree

<div id="cart"> <h3>Your Selection</h3> <table> <tbody>…</tbody> <tfoot>…</tfoot> </table> <input wicket:id="checkout" type="button" value="Check ou </div>

Page 125: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao(); private Cart cart = new Cart();

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses();

add(new ListView<Cheese>("cheese", cheeses) {…}); add(new ListView<Cheese>("item", cart.getItems()) {…}) } }

Page 126: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao(); private Cart cart = new Cart();

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses();

add(new ListView<Cheese>("cheese", cheeses) {…}); add(new ListView<Cheese>("item", cart.getItems()) {…}) add(new Link<Void>("checkout") {}); } }

Page 127: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao(); private Cart cart = new Cart();

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses();

add(new ListView<Cheese>("cheese", cheeses) {…}); add(new ListView<Cheese>("item", cart.getItems()) {…}) add(new Link<Void>("checkout") { @Override public void onClick() { } }); } }

Page 128: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { private CheeseDao cheeseDao = new CheeseDao(); private Cart cart = new Cart();

public Index() { List<Cheese> cheeses = cheeseDao.getCheeses();

add(new ListView<Cheese>("cheese", cheeses) {…}); add(new ListView<Cheese>("item", cart.getItems()) {…}) add(new Link<Void>("checkout") { @Override public void onClick() { setResponsePage(new CheckoutPage(cart)); } }); } }

Page 129: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { private Cart cart = new Cart();

public CheckoutPage(Cart cart) { this.cart = cart; } }

Page 130: Apache Wicket and Java EE sitting in a tree

5. implement checkout

Page 131: Apache Wicket and Java EE sitting in a tree
Page 132: Apache Wicket and Java EE sitting in a tree

<form > <h3>Check out</h3> <p>Please enter your billing address.</p> <table> <tr> <th>Name</th> <td><input type="text" /></td> </tr> <tr> <th>Street</th> <td><input type="text" /></td> </tr> <tr> <th>Zipcode</th> <td><input type="text" /></td> </tr> <tr> <th>City</th> <td><input type="text" /></td> </tr>

Page 133: Apache Wicket and Java EE sitting in a tree

<form wicket:id="form"> <h3>Check out</h3> <p>Please enter your billing address.</p> <table> <tr> <th>Name</th> <td><input type="text" /></td> </tr> <tr> <th>Street</th> <td><input type="text" /></td> </tr> <tr> <th>Zipcode</th> <td><input type="text" /></td> </tr> <tr> <th>City</th> <td><input type="text" /></td> </tr>

Page 134: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { private Cart cart;

public CheckoutPage(Cart cart) { this.cart = cart; } }

Page 135: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { private Cart cart;

public CheckoutPage(Cart cart) { this.cart = cart;

Form<Void> form = new Form<Void>("form") {}; add(form); } }

Page 136: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { private Cart cart;

public CheckoutPage(Cart cart) { this.cart = cart;

Form<Void> form = new Form<Void>("form") { @Override protected void onSubmit() { } }; add(form); } }

Page 137: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { private Cart cart;

private Order order = new Order();

public CheckoutPage(Cart cart) { this.cart = cart;

Form<Void> form = new Form<Void>("form") { @Override protected void onSubmit() { } }; add(form); } }

Page 138: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { private Cart cart;

private Order order = new Order();

@EJB private OrderDao orders;

public CheckoutPage(Cart cart) { this.cart = cart;

Form<Void> form = new Form<Void>("form") { @Override protected void onSubmit() { } }; add(form); } }

Page 139: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { … public CheckoutPage(Cart cart) { this.cart = cart; Form<Void> form = new Form<Void>("form") { @Override protected void onSubmit() { } }; add(form); } }

Page 140: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { … public CheckoutPage(Cart cart) { this.cart = cart;

Form<Void> form = new Form<Void>("form") { @Override protected void onSubmit() { for (Cheese cheese : cart.getItems()) { } } }; add(form); } }

Page 141: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { … public CheckoutPage(Cart cart) { this.cart = cart;

Form<Void> form = new Form<Void>("form") { @Override protected void onSubmit() { for (Cheese cheese : cart.getItems()) { OrderItem item = new OrderItem(); item.setOrder(order); item.setCheese(cheese); order.getItems().add(item); } } }; add(form); } }

Page 142: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { … public CheckoutPage(Cart cart) { this.cart = cart;

Form<Void> form = new Form<Void>("form") { @Override protected void onSubmit() { for (Cheese cheese : cart.getItems()) { OrderItem item = new OrderItem(); item.setOrder(order); item.setCheese(cheese); order.getItems().add(item); } orders.save(order); } }; add(form); } }

Page 143: Apache Wicket and Java EE sitting in a tree

6. make Cart Conversation Scoped

Page 144: Apache Wicket and Java EE sitting in a tree

What does the navigation between shopping and checkout look like?

Page 145: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { public Index() { … add(new Link<Void>("checkout") { @Override public void onClick() { setResponsePage(new CheckoutPage(cart)); } }); } }

public class CheckoutPage extends WebPage { private Cart cart;

public CheckoutPage(Cart cart) { this.cart = cart; … } }

Page 146: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { public Index() { … add(new Link<Void>("checkout") { @Override public void onClick() { setResponsePage(new CheckoutPage(cart)); } }); } }

public class CheckoutPage extends WebPage { private Cart cart;

public CheckoutPage(Cart cart) { this.cart = cart; … } }

Page 147: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { public Index() { … add(new Link<Void>("checkout") { @Override public void onClick() { setResponsePage(new CheckoutPage(cart)); } }); } }

public class CheckoutPage extends WebPage { private Cart cart;

public CheckoutPage(Cart cart) { this.cart = cart; … } }

Cart should be conversation scoped

Page 148: Apache Wicket and Java EE sitting in a tree

public class Cart implements Serializable { public Cart() { }

public void setItems(List<Cheese> items) { this.items = items; }

public List<Cheese> getItems() { return items; }

public double getTotal() { return items.stream().mapToDouble(Cheese::getPrice).su } }

Page 149: Apache Wicket and Java EE sitting in a tree

@ConversationScoped public class Cart implements Serializable { private List<Cheese> items = new ArrayList<>();

public Cart() { }

public void setItems(List<Cheese> items) { this.items = items; }

public List<Cheese> getItems() { return items; }

public double getTotal() { return items.stream().mapToDouble(Cheese::getPrice).su } }

Page 150: Apache Wicket and Java EE sitting in a tree

Let's get this conversation started

Page 151: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { … public Index() { … add(new Link<Void>("checkout") { @Override public void onClick() { setResponsePage(new CheckoutPage(cart)); } }); } }

Page 152: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { … @Inject private Conversation shopping;

public Index() { … add(new Link<Void>("checkout") { @Override public void onClick() { setResponsePage(new CheckoutPage(cart)); } }); } }

Page 153: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { … @Inject private Conversation shopping;

public Index() { … shopping.begin(); … add(new Link<Void>("checkout") { @Override public void onClick() { setResponsePage(new CheckoutPage(cart)); } }); } }

Page 154: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { … @Inject private Conversation shopping;

@Inject private Cart cart = new Cart();

public Index() { … shopping.begin(); … add(new Link<Void>("checkout") { @Override public void onClick() { setResponsePage(new CheckoutPage(cart)); } }); } }

Page 155: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { … @Inject private Conversation shopping;

@Inject private Cart cart;

public Index() { … shopping.begin(); … add(new Link<Void>("checkout") { @Override public void onClick() { setResponsePage(new CheckoutPage(cart)); } }); } }

Page 156: Apache Wicket and Java EE sitting in a tree

public class Index extends WebPage { … @Inject private Conversation shopping;

@Inject private Cart cart;

public Index() { … shopping.begin(); … add(new Link<Void>("checkout") { @Override public void onClick() { setResponsePage(new CheckoutPage()); } }); } }

Page 157: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { @EJB private OrderDao orders;

private Order order = new Order();

private Cart cart;

public CheckoutPage(Cart cart) { this.cart = cart;

Form<Void> form = new Form<Void>("form") {…}; add(form); } }

Page 158: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { @EJB private OrderDao orders;

private Order order = new Order();

private Cart cart;

public CheckoutPage() { this.cart = cart;

Form<Void> form = new Form<Void>("form") {…}; add(form); } }

Page 159: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { @EJB private OrderDao orders;

private Order order = new Order();

private Cart cart;

public CheckoutPage() { Form<Void> form = new Form<Void>("form") {…}; add(form); } }

Page 160: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { @EJB private OrderDao orders;

private Order order = new Order();

@Inject private Cart cart;

public CheckoutPage() { Form<Void> form = new Form<Void>("form") {…}; add(form); } }

Page 161: Apache Wicket and Java EE sitting in a tree

Let's end this conversation

Page 162: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { … @Inject private Cart cart;

public CheckoutPage() { Form<Void> form = new Form<Void>("form") {…}; add(form); } }

Page 163: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { … @Inject private Cart cart;

public CheckoutPage() { Form<Void> form = new Form<Void>("form") { @Override protected void onSubmit() { for (Cheese cheese : cart.getItems()) {…} orders.save(order); } }; add(form); } }

end conversation here...

Page 164: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { … @Inject private Conversation shopping;

@Inject private Cart cart;

public CheckoutPage() { Form<Void> form = new Form<Void>("form") { @Override protected void onSubmit() { for (Cheese cheese : cart.getItems()) {} orders.save(order); } }; add(form); } }

Page 165: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { … @Inject private Conversation shopping;

@Inject private Cart cart;

public CheckoutPage() { Form<Void> form = new Form<Void>("form") { @Override protected void onSubmit() { for (Cheese cheese : cart.getItems()) {} orders.save(order); shopping.end(); } }; add(form); } }

Page 166: Apache Wicket and Java EE sitting in a tree
Page 167: Apache Wicket and Java EE sitting in a tree

localhost:8080/cheesr/?0&cid=1 ⟳

Page 168: Apache Wicket and Java EE sitting in a tree
Page 169: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { … @Inject private Conversation shopping;

@Inject private Cart cart;

public CheckoutPage() { Form<Void> form = new Form<Void>("form") { @Override protected void onSubmit() { for (Cheese cheese : cart.getItems()) {} orders.save(order); shopping.end(); } }; add(form); } }

Page 170: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { … @Inject private Conversation shopping;

@Inject private Cart cart;

public CheckoutPage() { Form<Void> form = new Form<Void>("form") { @Override protected void onSubmit() { for (Cheese cheese : cart.getItems()) {} orders.save(order); shopping.end(); } }; add(form); } }

Page 171: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { … @Inject private Conversation shopping;

@Inject private Cart cart;

public CheckoutPage() { Form<Void> form = new Form<Void>("form") { @Override protected void onSubmit() { for (Cheese cheese : cart.getItems()) {} orders.save(order); shopping.end(); } }; add(form); } }

Page 172: Apache Wicket and Java EE sitting in a tree

public class CheckoutPage extends WebPage { … @Inject private Conversation shopping;

@Inject private Cart cart;

public CheckoutPage() { Form<Void> form = new Form<Void>("form") { @Override protected void onSubmit() { for (Cheese cheese : cart.getItems()) {} orders.save(order); shopping.end(); setResponsePage(Index.class); } }; add(form); }

Page 173: Apache Wicket and Java EE sitting in a tree

• Add wicket-cdi-1.1 and javax.cdi-api

• Configure Wicket's CdiConfiguration

• Use @Inject injection and @ConversationScoped

• Use NonContextual in non-managed objects

Page 174: Apache Wicket and Java EE sitting in a tree

Injection (EJB, CDI)

Conversations (CDI)

JPA

Bean validation

Testing with Arquillian

Page 175: Apache Wicket and Java EE sitting in a tree

Cheese, Order, OrderItem now @Entity

Order → OrderItem@OneToMany(fetchType=LAZY)

OrderItem → Cheese, OrderItem → Order@ManyToOne(optional=false)

CheeseDao, OrderDao now @Stateless@TransactionAttribute(REQUIRED)

Page 176: Apache Wicket and Java EE sitting in a tree

A refreshing modelA model that reloads data from DB for every render

Page 177: Apache Wicket and Java EE sitting in a tree

public class OrdersModel {}

Page 178: Apache Wicket and Java EE sitting in a tree

public class OrdersModel extends LoadableDetachableModel<List<Order>> { }

Page 179: Apache Wicket and Java EE sitting in a tree

public class OrdersModel extends LoadableDetachableModel<List<Order>> { @Override protected List<Order> load() { } }

Page 180: Apache Wicket and Java EE sitting in a tree

public class OrdersModel extends LoadableDetachableModel<List<Order>> { @Override protected List<Order> load() { return orders.list(); } }

Page 181: Apache Wicket and Java EE sitting in a tree

public class OrdersModel extends LoadableDetachableModel<List<Order>> { @Inject private OrderDao orders;

@Override protected List<Order> load() { return orders.list(); } }

Page 182: Apache Wicket and Java EE sitting in a tree

public class OrdersModel extends LoadableDetachableModel<List<Order>> { @Inject private OrderDao orders;

public OrdersModel() { }

@Override protected List<Order> load() { return orders.list(); } }

Page 183: Apache Wicket and Java EE sitting in a tree

public class OrdersModel extends LoadableDetachableModel<List<Order>> { @Inject private OrderDao orders;

public OrdersModel() { NonContextual.of(OrdersModel.class).inject(this); }

@Override protected List<Order> load() { return orders.list(); } }

Page 184: Apache Wicket and Java EE sitting in a tree

public class OrdersPage extends WebPage { public OrdersPage() { add(new ListView<Order>("items", new OrdersModel()) { @Override protected void populateItem(ListItem<Order> item) { Order o = item.getModelObject(); item.add(new Label("id", o.getId())); item.add(new Label("name", o.getName())); item.add(new Label("total", o.getTotal())); } }); } }

Page 185: Apache Wicket and Java EE sitting in a tree

public class OrdersPage extends WebPage { public OrdersPage() { } }

Page 186: Apache Wicket and Java EE sitting in a tree

public class OrdersPage extends WebPage { public OrdersPage() { add(new ListView<Order>("items", new OrdersModel()) { }); } }

Page 187: Apache Wicket and Java EE sitting in a tree

public class OrdersPage extends WebPage { public OrdersPage() { add(new ListView<Order>("items", new OrdersModel()) { @Override protected void populateItem(ListItem<Order> item) { } }); } }

Page 188: Apache Wicket and Java EE sitting in a tree

public class OrdersPage extends WebPage { public OrdersPage() { add(new ListView<Order>("items", new OrdersModel()) { @Override protected void populateItem(ListItem<Order> item) { Order o = item.getModelObject(); item.add(new Label("id", o.getId())); item.add(new Label("name", o.getName())); item.add(new Label("total", o.getTotal())); } }); } }

Page 189: Apache Wicket and Java EE sitting in a tree
Page 190: Apache Wicket and Java EE sitting in a tree

Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.cheesr.entities.Order.items, could not initialize proxy - no Session at org.hibernate.collection.internal.AbstractPersistentCollection.throw at org.hibernate.collection.internal.AbstractPersistentCollection.withT at org.hibernate.collection.internal.AbstractPersistentCollection.initi at org.hibernate.collection.internal.AbstractPersistentCollection.read( at org.hibernate.collection.internal.PersistentBag.iterator(PersistentB at java.util.Spliterators$IteratorSpliterator.estimateSize(Spliterators at java.util.Spliterator.getExactSizeIfKnown(Spliterator.java:408) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:511 at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.j at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.jav at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234 at java.util.stream.DoublePipeline.collect(DoublePipeline.java:476) at java.util.stream.DoublePipeline.sum(DoublePipeline.java:388) at com.cheesr.entities.Order.getTotal(Order.java:94) at com.cheesr.web.OrdersPage$1.populateItem(OrdersPage.java:22) at org.apache.wicket.markup.html.list.ListView.onPopulate(ListView.java at org.apache.wicket.markup.repeater.AbstractRepeater.onBeforeRender(Ab at org.apache.wicket.Component.internalBeforeRender(Component.java:949) at org.apache.wicket.Component.beforeRender(Component.java:1017) at org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupConta ... 50 more

Page 191: Apache Wicket and Java EE sitting in a tree

LazyInitializationException failed to lazily initialize a collection of role: com.cheesr.entities.Order.items, could not initialize proxy - no Session

Page 192: Apache Wicket and Java EE sitting in a tree

LazyInitException: AARGHWhy and how to get rid of them

Page 193: Apache Wicket and Java EE sitting in a tree

@Stateless @TransactionAttribute(TransactionAttributeType.REQUIRED) public class OrderDao implements Serializable {

public void save(Order order) {…}

public List<Order> list() {…} }

Page 194: Apache Wicket and Java EE sitting in a tree

@Stateless @TransactionAttribute(TransactionAttributeType.REQUIRED) public class OrderDao implements Serializable {

public void save(Order order) {…}

public List<Order> list() {…} }

Page 195: Apache Wicket and Java EE sitting in a tree

After dao.list() JPA session ends

Page 196: Apache Wicket and Java EE sitting in a tree

@Entity @Table(name = "Orders") public class Order implements Serializable { @Id @GeneratedValue private Long id; private String name; private String street; private String zipcode; private String city; private String country;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true) private List<OrderItem> items = new ArrayList<>();

public Long getId() { return id;

Page 197: Apache Wicket and Java EE sitting in a tree

@Entity @Table(name = "Orders") public class Order implements Serializable { @Id @GeneratedValue private Long id; private String name; private String street; private String zipcode; private String city; private String country;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true) private List<OrderItem> items = new ArrayList<>();

public Long getId() { return id;

Page 198: Apache Wicket and Java EE sitting in a tree

Generates lazy proxies, resolved upon request

Page 199: Apache Wicket and Java EE sitting in a tree

public class OrdersPage extends WebPage { public OrdersPage() { add(new ListView<Order>("items", new OrdersModel()) { @Override protected void populateItem(ListItem<Order> item) { Order o = item.getModelObject(); item.add(new Label("id", o.getId())); item.add(new Label("name", o.getName())); item.add(new Label("total", o.getTotal())); } }); } }

Page 200: Apache Wicket and Java EE sitting in a tree

public class OrdersPage extends WebPage { public OrdersPage() { add(new ListView<Order>("items", new OrdersModel()) { @Override protected void populateItem(ListItem<Order> item) { Order o = item.getModelObject(); item.add(new Label("id", o.getId())); item.add(new Label("name", o.getName())); item.add(new Label("total", o.getTotal())); } }); } }

Page 201: Apache Wicket and Java EE sitting in a tree

getTotal() requests upon the proxy: LazyInitException

Page 202: Apache Wicket and Java EE sitting in a tree

Fix LazyInitExceptionsExtend transaction for whole request (using a Servlet 3.0 @WebFilter)

Page 203: Apache Wicket and Java EE sitting in a tree

@WebFilter(filterName = "Cheesr", value = "/*", initParams = { @WebInitParam( name = "applicationClassName", value = "com.cheesr.web.WicketApplication"), @WebInitParam( name = "filterMappingUrlPattern", value = "/*") }) public class CheesrFilter extends WicketFilter { @Override public void doFilter(ServletRequest req, ServletResponse super.doFilter(request, response, chain); } }

Page 204: Apache Wicket and Java EE sitting in a tree

@WebFilter(filterName = "Cheesr", value = "/*", initParams = { @WebInitParam( name = "applicationClassName", value = "com.cheesr.web.WicketApplication"), @WebInitParam( name = "filterMappingUrlPattern", value = "/*") }) public class CheesrFilter extends WicketFilter { @Transactional @Override public void doFilter(ServletRequest req, ServletResponse super.doFilter(request, response, chain); } }

Page 205: Apache Wicket and Java EE sitting in a tree
Page 206: Apache Wicket and Java EE sitting in a tree

Rolling back a transaction

Page 207: Apache Wicket and Java EE sitting in a tree

When you use a reloading model e.g. CheeseLoadableModel

And you use container managed transactions @Transactional WicketFilter

Then be careful of unwanted modifications

Page 208: Apache Wicket and Java EE sitting in a tree

Form<Cheese> form = new Form<Cheese>("form", cheeseModel) { @Override protected void onSubmit() { Cheese cheese = getModelObject(); if (cheese.getPrice() < 1) { error("Price must be €1,- or higher"); } else { cheeseDao.save(cheese); setResponsePage(Index.class); } } }; add(form);

Page 209: Apache Wicket and Java EE sitting in a tree
Page 210: Apache Wicket and Java EE sitting in a tree
Page 211: Apache Wicket and Java EE sitting in a tree
Page 212: Apache Wicket and Java EE sitting in a tree

"No news is good news..." – Container Managed Transactions

Page 213: Apache Wicket and Java EE sitting in a tree

Form<Cheese> form = new Form<Cheese>("form", cheeseModel) { @Override protected void onSubmit() { Cheese cheese = getModelObject(); if (cheese.getPrice() < 1) { error("Price must be €1,- or higher"); } else { cheeseDao.save(cheese); setResponsePage(Index.class); } } }; add(form);

Page 214: Apache Wicket and Java EE sitting in a tree

Form<Cheese> form = new Form<Cheese>("form", cheeseModel) { @Override protected void onSubmit() { Cheese cheese = getModelObject(); if (cheese.getPrice() < 1) { transactionBean.setTransactionRollbackOnly(); error("Price must be €1,- or higher"); } else { cheeseDao.save(cheese); setResponsePage(Index.class); } } }; add(form);

Page 215: Apache Wicket and Java EE sitting in a tree

@Stateless @TransactionAttribute(TransactionAttributeType.REQUIRED) public class TransactionBean { @Resource private SessionContext context;

public void setTransactionRollbackOnly() { context.setRollbackOnly(); } }

Page 216: Apache Wicket and Java EE sitting in a tree

When you use a reloading model e.g. CheeseLoadableModel

And you use container managed transactions @Transactional WicketFilter

Then be careful of unwanted modifications and rollback the transaction

Page 217: Apache Wicket and Java EE sitting in a tree

Injection (EJB, CDI)

Conversations (CDI)

JPA

Bean validation

Testing with Arquillian

Page 218: Apache Wicket and Java EE sitting in a tree

Bean ValidationSingle Point of Definition

Page 219: Apache Wicket and Java EE sitting in a tree

Add dependencies

Add validation constraints

Configure Wicket

Add Validators to components

Steps

Page 220: Apache Wicket and Java EE sitting in a tree

<!-- BEAN VALIDATION DEPENDENCIES --> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.wicket</groupId> <artifactId>wicket-bean-validation</artifactId> </dependency>

Page 221: Apache Wicket and Java EE sitting in a tree

@Entity @Table(name = "Orders") public class Order implements Serializable { @Id @GeneratedValue private Long id;

private String name;

private String street;

private String zipcode;

private String city;

private String country;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "order", ca private List<OrderItem> items = new ArrayList<>();

Page 222: Apache Wicket and Java EE sitting in a tree

@Entity @Table(name = "Orders") public class Order implements Serializable { @Id @GeneratedValue private Long id;

@NotNull private String name;

private String street;

private String zipcode;

private String city;

private String country;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "order", ca private List<OrderItem> items = new ArrayList<>();

Page 223: Apache Wicket and Java EE sitting in a tree

@Entity @Table(name = "Orders") public class Order implements Serializable { @Id @GeneratedValue private Long id;

@NotNull private String name;

@Size(min = 3, max = 20) @NotNull private String street;

private String zipcode;

private String city;

private String country;

Page 224: Apache Wicket and Java EE sitting in a tree

@Entity @Table(name = "Orders") public class Order implements Serializable { @Id @GeneratedValue private Long id;

@NotNull private String name;

@Size(min = 3, max = 20) @NotNull private String street;

@Pattern(regexp = "\\d{4} [A-Z]{2}") @NotNull private String zipcode;

private String city;

Page 225: Apache Wicket and Java EE sitting in a tree

public void init() { super.init();

BeanValidationConfiguration beanValidation = new BeanValidationConfiguration(); beanValidation.configure(this);

CdiConfiguration cdiConfiguration = new CdiConfiguration(); cdiConfiguration .setPropagation(ConversationPropagation.ALL); cdiConfiguration.configure(this);

getComponentInstantiationListeners().add( new JavaEEComponentInjector(this, new WildflyWicketJndiNamingStrategy()));

mountPage("/checkout", CheckoutPage.class); mountPage("/orders", OrdersPage.class); }

Page 226: Apache Wicket and Java EE sitting in a tree

TextField<String> nameField = new TextField<>("name", PropertyModel.of(this, "order.nam form.add(nameField);

TextField<String> streetField = new TextField<>("street", PropertyModel.of(this, "order.s form.add(streetField);

Page 227: Apache Wicket and Java EE sitting in a tree

TextField<String> nameField = new TextField<>("name", PropertyModel.of(this, "order.nam nameField.add(new PropertyValidator<>()); form.add(nameField);

TextField<String> streetField = new TextField<>("street", PropertyModel.of(this, "order.s form.add(streetField);

Page 228: Apache Wicket and Java EE sitting in a tree

TextField<String> nameField = new TextField<>("name", PropertyModel.of(this, "order.nam nameField.add(new PropertyValidator<>()); form.add(nameField);

TextField<String> streetField = new TextField<>("street", PropertyModel.of(this, "order.s streetField.add(new PropertyValidator<>()); form.add(streetField);

Page 229: Apache Wicket and Java EE sitting in a tree

add wicket-bean-validation and javax.validation:validation-api to project

configure BeanValidationConfiguration in init()

add PropertyValidator to fields

Page 230: Apache Wicket and Java EE sitting in a tree

Injection (EJB, CDI)

Conversations (CDI)

JPA

Bean validation

Testing with Arquillian

Page 231: Apache Wicket and Java EE sitting in a tree

Testing with WicketTester

Page 232: Apache Wicket and Java EE sitting in a tree

public class TestIndex { private WicketTester tester;

@Before public void setUp() { WicketApplication app = new WicketApplication(); tester = new WicketTester(app); }

@Test public void homepageRendersSuccessfully() { tester.startPage(Index.class);

tester.assertRenderedPage(Index.class); } }

Page 233: Apache Wicket and Java EE sitting in a tree
Page 234: Apache Wicket and Java EE sitting in a tree

• No bean manager

• No data source

• No persistence context

• No transactions

• No EJBs

NO TESTS

Page 235: Apache Wicket and Java EE sitting in a tree

ArquillianNo more mocks. No more container lifecycle and deployment hassles. Just real tests!

Page 236: Apache Wicket and Java EE sitting in a tree

Add Arquillian dependencies to project

Build deployable archivewith all necessary resources

Create a test case

Execute test case with Arquillian

Steps

Page 237: Apache Wicket and Java EE sitting in a tree

<!-- ARQUILLIAN DEPENDENCY FOR TESTING --> <dependency> <groupId>org.jboss.arquillian.junit</groupId> <artifactId>arquillian-junit-container</artifactId> <scope>test</scope> </dependency>

Page 238: Apache Wicket and Java EE sitting in a tree

<!-- ARQUILLIAN DEPENDENCY FOR TESTING --> <dependency> <groupId>org.jboss.arquillian.junit</groupId> <artifactId>arquillian-junit-container</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.shrinkwrap.descriptors</groupId> <artifactId>shrinkwrap-descriptors-impl-javaee</artifact <scope>test</scope> </dependency>

Page 239: Apache Wicket and Java EE sitting in a tree

<!-- ARQUILLIAN DEPENDENCY FOR TESTING --> <dependency> <groupId>org.jboss.arquillian.junit</groupId> <artifactId>arquillian-junit-container</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.shrinkwrap.descriptors</groupId> <artifactId>shrinkwrap-descriptors-impl-javaee</artifact <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.shrinkwrap.resolver</groupId> <artifactId>shrinkwrap-resolver-impl-maven</artifactId> <scope>test</scope> </dependency>

Page 240: Apache Wicket and Java EE sitting in a tree

Add Arquillian dependencies to project

Build deployable archivewith all necessary resources

Create a test case

Execute test case with Arquillian

Steps

Page 241: Apache Wicket and Java EE sitting in a tree

public class TestIndex { private WicketTester tester;

@Before public void setUp() { WicketApplication app = new WicketApplication(); tester = new WicketTester(app); }

@Test public void homepageRendersSuccessfully() { tester.startPage(Index.class);

tester.assertRenderedPage(Index.class); } }

Page 242: Apache Wicket and Java EE sitting in a tree

@RunWith(Arquillian.class) public class TestIndex { private WicketTester tester;

@Before public void setUp() { WicketApplication app = new WicketApplication(); tester = new WicketTester(app); }

@Test public void homepageRendersSuccessfully() { tester.startPage(Index.class);

tester.assertRenderedPage(Index.class); } }

Page 243: Apache Wicket and Java EE sitting in a tree

@RunWith(Arquillian.class) public class TestIndex { @Deployment public static WebArchive deployment() {…}

private WicketTester tester;

@Before public void setUp() { WicketApplication app = new WicketApplication(); tester = new WicketTester(app); }

@Test public void homepageRendersSuccessfully() { tester.startPage(Index.class);

tester.assertRenderedPage(Index.class); } }

Page 244: Apache Wicket and Java EE sitting in a tree

@Deployment public static WebArchive deployment() { File[] dependencies = Maven.configureResolver() .workOffline() .loadPomFromFile("pom.xml") .importCompileAndRuntimeDependencies() .resolve() .withTransitivity() .as(File.class); }

Page 245: Apache Wicket and Java EE sitting in a tree

@Deployment public static WebArchive deployment() { File[] dependencies = Maven.configureResolver() .workOffline() .loadPomFromFile("pom.xml") .importCompileAndRuntimeDependencies() .resolve() .withTransitivity() .as(File.class); WebArchive war = ShrinkWrap .create(WebArchive.class) .addAsResource(new File("target/classes"), "") .addAsLibraries(dependencies) .addAsWebInfResource( new File("src/main/webapp/WEB-INF/beans.xml")) .addAsWebInfResource( new File("src/main/webapp/WEB-INF/cheesr-ds.xml") return war; }

Page 246: Apache Wicket and Java EE sitting in a tree

6ea1e1a7-7f07-4318-8f70-ec7b8d5edbcc.war: /WEB-INF/ /WEB-INF/lib/ /WEB-INF/lib/annotations-3.0.0.jar /WEB-INF/lib/wicketstuff-javaee-inject-6.17.0.jar /WEB-INF/lib/javax.inject-1.jar /WEB-INF/lib/wicket-cdi-1.1-6.18.0.jar /WEB-INF/lib/cglib-2.2.2.jar /WEB-INF/lib/fest-util-1.1.6.jar /WEB-INF/lib/wicket-ioc-6.18.0.jar /WEB-INF/lib/wicket-bean-validation-6.18.0.jar /WEB-INF/lib/wicket-request-6.18.0.jar /WEB-INF/lib/log4j-1.2.17.jar /WEB-INF/lib/asm-3.3.1.jar /WEB-INF/lib/fest-assert-1.4.jar /WEB-INF/lib/validation-api-1.1.0.Final.jar /WEB-INF/lib/slf4j-log4j12-1.7.7.jar /WEB-INF/lib/slf4j-api-1.7.7.jar /WEB-INF/lib/jcl-over-slf4j-1.7.7.jar /WEB-INF/lib/wicket-core-6.18.0.jar /WEB-INF/lib/wicket-util-6.18.0.jar /WEB-INF/cheesr-ds.xml /WEB-INF/classes/ /WEB-INF/classes/wildfly-doesnt-need-log4j.properties /WEB-INF/classes/META-INF/ /WEB-INF/classes/META-INF/persistence.xml /WEB-INF/classes/com/ /WEB-INF/classes/com/cheesr/ /WEB-INF/classes/com/cheesr/domain/ /WEB-INF/classes/com/cheesr/domain/Cart.class /WEB-INF/classes/com/cheesr/domain/MessageOfTheDay.class /WEB-INF/classes/com/cheesr/web/ /WEB-INF/classes/com/cheesr/web/CheckoutPage$2.class /WEB-INF/classes/com/cheesr/web/Index$2$1.class /WEB-INF/classes/com/cheesr/web/OrdersPage.class /WEB-INF/classes/com/cheesr/web/WicketApplication.class /WEB-INF/classes/com/cheesr/web/Index$1$1.class /WEB-INF/classes/com/cheesr/web/Index.html /WEB-INF/classes/com/cheesr/web/WicketApplication$WildflyWicketJndiNamingStrategy.class /WEB-INF/classes/com/cheesr/web/Index$2.class /WEB-INF/classes/com/cheesr/web/CheckoutPage.class /WEB-INF/classes/com/cheesr/web/CheckoutPage.html /WEB-INF/classes/com/cheesr/web/Index.class /WEB-INF/classes/com/cheesr/web/CheesrFilter.class /WEB-INF/classes/com/cheesr/web/MessageModel.class /WEB-INF/classes/com/cheesr/web/Index$3.class /WEB-INF/classes/com/cheesr/web/OrdersModel.class

Page 247: Apache Wicket and Java EE sitting in a tree

Add Arquillian dependencies to project

Build deployable archivewith all necessary resources

Create a test case

Execute test case with Arquillian

Steps

Page 248: Apache Wicket and Java EE sitting in a tree
Page 249: Apache Wicket and Java EE sitting in a tree

Add Arquillian dependencies to project

Build deployable archivewith all necessary resources

Create a test case

Execute test case with Arquillian

Steps

Page 250: Apache Wicket and Java EE sitting in a tree

@Inject private Conversation conversation;

@EJB private CheeseDao cheeses;

@Inject private Cart cart;

@Test public void addCheeseToCart() { }

Page 251: Apache Wicket and Java EE sitting in a tree

public void addCheeseToCart() { }

Page 252: Apache Wicket and Java EE sitting in a tree

public void addCheeseToCart() { Cheese edam = cheeses.byCode("edam"); }

Page 253: Apache Wicket and Java EE sitting in a tree

public void addCheeseToCart() { Cheese edam = cheeses.byCode("edam");

tester.startPage(Index.class); tester.assertRenderedPage(Index.class); }

Page 254: Apache Wicket and Java EE sitting in a tree

public void addCheeseToCart() { Cheese edam = cheeses.byCode("edam");

tester.startPage(Index.class); tester.assertRenderedPage(Index.class); tester.assertModelValue("cheese:1", edam); }

Page 255: Apache Wicket and Java EE sitting in a tree

public void addCheeseToCart() { Cheese edam = cheeses.byCode("edam");

tester.startPage(Index.class); tester.assertRenderedPage(Index.class); tester.assertModelValue("cheese:1", edam);

tester.clickLink("cheese:1:add"); assertThat(cart.getItems().size(), is(1)); tester.assertModelValue("item:0", edam); }

Page 256: Apache Wicket and Java EE sitting in a tree

public void addCheeseToCart() { Cheese edam = cheeses.byCode("edam");

tester.startPage(Index.class); tester.assertRenderedPage(Index.class); tester.assertModelValue("cheese:1", edam);

tester.clickLink("cheese:1:add"); assertThat(cart.getItems().size(), is(1)); tester.assertModelValue("item:0", edam);

tester.clickLink("cheese:1:add"); assertThat(cart.getItems().size(), is(2)); assertThat(cart.getItems().get(0), is(edam)); assertThat(cart.getItems().get(1), is(edam)); }

Page 257: Apache Wicket and Java EE sitting in a tree

public void addCheeseToCart() { Cheese edam = cheeses.byCode("edam");

tester.startPage(Index.class); tester.assertRenderedPage(Index.class); tester.assertModelValue("cheese:1", edam);

tester.clickLink("cheese:1:add"); assertThat(cart.getItems().size(), is(1)); tester.assertModelValue("item:0", edam);

tester.clickLink("cheese:1:add"); assertThat(cart.getItems().size(), is(2)); assertThat(cart.getItems().get(0), is(edam)); assertThat(cart.getItems().get(1), is(edam));

tester.clickLink("checkout"); tester.assertRenderedPage(CheckoutPage.class); }

Page 258: Apache Wicket and Java EE sitting in a tree
Page 259: Apache Wicket and Java EE sitting in a tree

with Arquillian you can test Wicket pages with JPA, CDI, EJB

add Arquillian dependencies to POM,

add arquillian.xml for container connection

create a deployment

write and run your tests

Page 260: Apache Wicket and Java EE sitting in a tree

Injection (EJB, CDI)

Conversations (CDI)

JPA

Bean validation

Arquillian

Page 261: Apache Wicket and Java EE sitting in a tree

Wicket and Java EE?

Page 262: Apache Wicket and Java EE sitting in a tree
Page 263: Apache Wicket and Java EE sitting in a tree

Questions?