Simple Web Development in Java

50 %
50 %
Information about Simple Web Development in Java

Published on March 1, 2014

Author: vtence



The slides of my talk at Confoo 2014 in Montréal, Qc.

Let's get back to simplicity when doing Java web development. Forget about DI frameworks, ORMs and complex build tools and see how we can develop well-tested, well-crafted web applications using only simple tools, libraries and techniques.

In this talk, I will share my experience rewriting a web application based on Spring MVC, Spring, Hibernate and Maven with only Simple and JDBC. We'll discuss the benefits and challenges of simplicity.

Simple Web Development in Java Vincent Tencé @testinfected

Déjà vu? You start a new project by assembling multiple libraries and frameworks It’s a lot of initial complexity One of the frameworks keeps getting in the way The framework feels like a prison It keeps surprising you with unintended behaviour

The Original Version • Spring with Spring MVC • Velocity and SiteMesh, UrlRewriteFilter • Hibernate, JPA, MySQL • Hibernate Validator • Maven • ... 53 jars!

The Challenge • Use simple tools and libraries • Framework (Web, ORM, DI) • DIYS (Do It Yourself Simply) • Ease of assembly, configuration and deployment • Minimum startup and shutdown costs • XML • Annotations

The Simple Version • Simple • Mustache • JDBC and MySQL • CLI • Buildr • 4 jars

Build File define 'petstore', [..] do define 'domain' do compile.with test.with HAMCREST package :jar end define 'persistence' do compile.with project(:domain) test.with HAMCREST, :flyway, :mysql, NO_LOG, [...] package :jar end define 'webapp' domain compile.with :simpleframework, :jmustache, [...] test.with HAMCREST, :antlr_runtime, :cssselectors, :hamcrest_dom, [...] test.with transitive(artifacts(:nekohtml, :htmlunit, :jmock_legacy)) package :jar end [...] end

Dependency Injection AttachmentStorage attachments = new FileSystemPhotoStore("/photos"); Connection connection = new ConnectionReference(request).get(); Transactor transactor = new JDBCTransactor(connection); ProductCatalog products = new ProductsDatabase(connection); ItemInventory items = new ItemsDatabase(connection); OrderBook orders = new OrdersDatabase(connection); ProcurementRequestHandler procurement = new PurchasingAgent(products, items, transactor) OrderNumberSequence orderNumbers = new OrderNumberDatabaseSequence(connection); Cashier cashier = new Cashier(orderNumbers, orders, transactor); Messages messages = new BundledMessages(ResourceBundle.getBundle("ValidationMessages")) Router router = Router.draw(new DynamicRoutes() {{ [...] }});

Routing [...] Router router = Router.draw(new DynamicRoutes() {{ get("/products").to(new ListProducts(products, attachments, pages.products())); post("/products").to(new CreateProduct(procurement)); get("/products/:product/items").to(new ListItems(items, pages.items())); post("/products/:product/items").to(new CreateItem(procurement)); get("/cart").to(new ShowCart(cashier, pages.cart())); post("/cart").to(new CreateCartItem(cashier)); get("/orders/new").to(new Checkout(cashier, pages.checkout())); get("/orders/:number").to(new ShowOrder(orders, pages.order())); post("/orders").to(new PlaceOrder(cashier)); delete("/logout").to(new Logout()); map("/").to(new StaticPage(pages.home())); }});

MVC public class ShowOrder implements Application { private final OrderBook orderBook; private final Page orderPage; public ShowOrder(OrderBook orderBook, Page orderPage) { this.orderBook = orderBook; this.orderPage = orderPage; } public void handle(Request request, Response response) throws Exception { String number = request.parameter("number"); Order order = orderBook.find(new OrderNumber(number)); orderPage.render(response, context().with("order", order)); } }

Data Access public class OrdersDatabase implements OrderBook { [...] public OrdersDatabase(Connection connection) { this.connection = connection; } private List<LineItem> findLineItemsOf(Order order) { return Select.from(lineItems). where("order_id = ?", idOf(order).get()). orderBy("order_line"). list(connection); } private Order findOrder(OrderNumber orderNumber) { return Select.from(orders, "_order"). leftJoin(payments, "payment", "_order.payment_id ="). where("_order.number = ?", orderNumber). first(connection); } [...] }

Transactions public class Cashier implements SalesAssistant { [...] public OrderNumber placeOrder(PaymentMethod paymentMethod) throws Exception { [...] QueryUnitOfWork<OrderNumber> order = new QueryUnitOfWork<OrderNumber>() { public OrderNumber query() throws Exception { OrderNumber nextNumber = orderNumberSequence.nextOrderNumber(); final Order order = new Order(nextNumber); order.addItemsFrom(cart);; orderBook.record(order); cart.clear(); return nextNumber; } }; return transactor.performQuery(order); } [...] }

Validation Constraints public class CreditCardDetails extends PaymentMethod implements Serializable { private final CreditCardType cardType; private final Constraint<String> cardNumber; private final NotNull<String> cardExpiryDate; private final Valid<Address> billingAddress; public CreditCardDetails(CreditCardType type, String number, String expiryDate, Address billingAddress) { this.cardType = type; this.cardNumber = Validates.both(notEmpty(number), correctnessOf(type, number)); this.cardExpiryDate = Validates.notNull(expiryDate); this.billingAddress = Validates.validityOf(billingAddress); } public String getCardNumber() { return cardNumber.get(); } [...] }

Validation public class Validator { public <T> Set<ConstraintViolation<?>> validate(T target) { Valid<T> valid = Validates.validityOf(target); valid.disableRootViolation(); ViolationsReport report = new ViolationsReport(); valid.check(Path.root(target), report); return report.violations(); } [...] }

Forms public class PaymentForm extends Form { public static PaymentForm parse(Request request) { return new PaymentForm(new CreditCardDetails( valueOf(request.parameter("card-type")), request.parameter("card-number"), request.parameter("expiry-date"), new Address(request.parameter("first-name"), request.parameter("last-name"), request.parameter("email")))); } private final Valid<CreditCardDetails> paymentDetails; public PaymentForm(CreditCardDetails paymentDetails) { this.paymentDetails = Validates.validityOf(paymentDetails); } public CreditCardType cardType() { return paymentDetails().getCardType(); } public CreditCardDetails paymentDetails() { return paymentDetails.get(); } }

Thoughts • Not very “enterprisy” • What are we missing? • Use a proven solution or develop our own? • Not a silver bullet

Takeaways • Avoid the temptation of frameworks • Use simple tools that do one thing and do it well • Build your own tools • Copy the best ideas; write only the simple code you need • Keep your tools simple and specialized

Thanks! • Simple version : • Spring version : • Web : • Data Mapping :

Add a comment

Related presentations

Presentación que realice en el Evento Nacional de Gobierno Abierto, realizado los ...

In this presentation we will describe our experience developing with a highly dyna...

Presentation to the LITA Forum 7th November 2014 Albuquerque, NM

Un recorrido por los cambios que nos generará el wearabletech en el futuro

Um paralelo entre as novidades & mercado em Wearable Computing e Tecnologias Assis...

Microsoft finally joins the smartwatch and fitness tracker game by introducing the...

Related pages

Java EE & Java Web Learning Trail - NetBeans Tutorials ...

Java EE & Java Web Learning Trail What is a Java ... Because many of the tasks involved in web application development can be ... Creating a Simple Web ...
Read more

Servlets and JSPs Tutorial: Learn Web Applications With Java

Servlets and JSPs Tutorial: Learn Web ... install for Java web application development. ... Java web applications is surprisingly simple, ...
Read more

Introduction to Java Web development - Tutorial - vogella

Java Web technologies. ... encapsulates the core functionality common to many Web applications as simple ... Getting started with Java Web development is ...
Read more

Java Web Application Tutorial for Beginners | JournalDev

Start with Java Web Development in Eclipse ... Java Web Application Tutorial for Beginners. ... web sites i found this article is very simple and ...
Read more

Getting Started with Web Applications - The Java EE 6 Tutorial

Chapter 3 Getting Started with Web Applications. A web application is a dynamic extension of a web or application server. Web applications are of the ...
Read more

Vincent Tencé | Simple Web Development In Java

Reading the following situations might evoke a feeling of déjà vu. a. You start a new development effort by assembling 5 to 10 (or more) libraries as a ...
Read more

Java Web Development with Eclipse WTP - Tutorial

The Eclipse WTP project provides tools for developing standard Java web applications and Java EE applications. Typical web artifacts in a Java environment ...
Read more

Creating a Simple Web Application Using a MySQL Database ...

Creating a Simple Web Application Using a ... Simple web applications can be designed using a ... For more information about Java web development, ...
Read more

Mkyong - Java web development tutorials

About is for Java and J2EE developers, all examples are simple and easy to understand, and well tested in my development environment.
Read more