65
Christian Kaltepoth | ingenit GmbH & Co. KG Beyond PrettyFaces Einführung in Rewrite

Beyond PrettyFaces - Einführung in Rewrite

Embed Size (px)

DESCRIPTION

W-JAX 2013 talk on Rewrite

Citation preview

Page 1: Beyond PrettyFaces - Einführung in Rewrite

Christian Kaltepoth | ingenit GmbH & Co. KG

Beyond PrettyFacesEinführung in Rewrite

Page 2: Beyond PrettyFaces - Einführung in Rewrite

URL-Rewriting

Page 3: Beyond PrettyFaces - Einführung in Rewrite

Wikipedia

A rewrite engine is software [...] that modifies a web URL's appearance.

This modification is called URL rewriting.

http://en.wikipedia.org/wiki/Rewrite_engine

Page 4: Beyond PrettyFaces - Einführung in Rewrite

Beispiel

http://www.onlineshop.de/b/ref=sa_menu_desk3?ie=UTF8&node=2193272340

http://www.onlineshop.de/elektronik

Page 5: Beyond PrettyFaces - Einführung in Rewrite

Sprechende RESTful URLs

http://www.javaserverfaces.org/news

http://jax.de/wjax2013/sessions

https://github.com/ocpsoft/rewrite/issues/87

http://stackoverflow.com/questions/tagged/jsf

Page 6: Beyond PrettyFaces - Einführung in Rewrite

Wozu das Ganze?

Page 7: Beyond PrettyFaces - Einführung in Rewrite

Vorteile

• Adressierbare Informationen– Wo bin ich hier?– "Vertrauen"

• Reload und Bookmarks• Einfache HTML Links

– Lose Kopplung

• Technologieneutralität

Page 8: Beyond PrettyFaces - Einführung in Rewrite

SEO

• Keywords in URL• Optimierung des Rankings

http://www.amazon.com/JavaServer-Faces-2-0-Complete-

Reference/dp/0071625097

Page 9: Beyond PrettyFaces - Einführung in Rewrite

PrettyFaces• JSF URL-Rewriting De-facto-Standard • RESTful URLs• Page Actions• Einfache Rewrite Engine• Dynamic Views• Integration mit JSF Navigation

Page 10: Beyond PrettyFaces - Einführung in Rewrite

Warum Rewrite?

Page 11: Beyond PrettyFaces - Einführung in Rewrite

API Abhängigkeiten

Servlet-spezifisch

JSF-spezifisch

Pre

ttyF

aces

Page 12: Beyond PrettyFaces - Einführung in Rewrite
Page 13: Beyond PrettyFaces - Einführung in Rewrite

Einschränkungen

• Mapping nur via Request Path• Eingeschränkte Konfiguration via XML• Annotation API „verbesserungswürdig“• Konvertierung nur eingeschränkt

möglich• Nicht besonders erweiterbar

Page 14: Beyond PrettyFaces - Einführung in Rewrite

Der Neuanfang

Page 15: Beyond PrettyFaces - Einführung in Rewrite

Was ist Rewrite?

Page 16: Beyond PrettyFaces - Einführung in Rewrite

Key Features

• Servlet basiertes Rewriting auf Basis einer Rule-Engine

• Framework Integration– JSF, CDI, Spring, Shiro, etc.

• Konfiguration: Java DSL + Annotations• Fokus auf Erweiterbarkeit• Open Source (Apache 2.0)

Page 17: Beyond PrettyFaces - Einführung in Rewrite

Begriffe

• Configuration:– Sortierte Liste

von Rules

• Rule:– Conditions– Operations– Priority

Page 18: Beyond PrettyFaces - Einführung in Rewrite

Rewriting Types

Inbound

Outbound

Page 19: Beyond PrettyFaces - Einführung in Rewrite

Inbound

GET /faces/home.xhtml HTTP/1.1Host: www.acme.comConnection: keep-alive[....]

Page 20: Beyond PrettyFaces - Einführung in Rewrite

Outbound

<a href="/faces/home.xhtml"> Getting started</a>

Page 21: Beyond PrettyFaces - Einführung in Rewrite

Java DSL

Page 22: Beyond PrettyFaces - Einführung in Rewrite

Warum?

• Typensichere Konfiguration• Code Assist durch IDE• Geführte Konfiguration• Erweiterbar• „Plain Java“

Page 23: Beyond PrettyFaces - Einführung in Rewrite

Java DSL

public class RewriteConfig extends HttpConfigurationProvider {

@Override public Configuration getConfiguration(ServletContext ctx) {

// Konfiguration „bauen“

}

@Override public int priority() { return 10; }

}

Page 24: Beyond PrettyFaces - Einführung in Rewrite

ConfigurationBuilder

return ConfigurationBuilder.begin() // Variante 1 .addRule() .when( /* condition */ ) .perform( /* operation */ ) // Variante 2 .addRule( /* rule */ )

;

Page 25: Beyond PrettyFaces - Einführung in Rewrite

Initial Redirect

http://www.acme.com/

http://www.acme.com/faces/home.xhtml

Redirect

Page 26: Beyond PrettyFaces - Einführung in Rewrite

Beispiel: Initial Redirect

.addRule()

.when( Direction.isInbound().and(Path.matches("/"))).perform( Redirect.permanent("/faces/home.xhtml"))

Page 27: Beyond PrettyFaces - Einführung in Rewrite

Der erste Rewrite

http://www.acme.com/faces/home.xhtml

http://www.acme.com/home

Page 28: Beyond PrettyFaces - Einführung in Rewrite

Der erste Rewrite

.addRule()

.when(Direction.isInbound().and( Path.matches("/home"))).perform(Forward.to("/faces/home.xhtml"))

.addRule()

.when(Direction.isOutbound().and( Path.matches("/faces/home.xhtml"))).perform(Substitute.with("/home"))

Page 29: Beyond PrettyFaces - Einführung in Rewrite

Einfacher: Joins

.addRule( Join.path("/home") .to("/faces/home.xhtml") )

Page 30: Beyond PrettyFaces - Einführung in Rewrite

Parameter

/faces/products.xhtml?category=books

/products/books

Page 31: Beyond PrettyFaces - Einführung in Rewrite

JSF 2.0 View Parameter

<f:metadata> <f:viewParam name="category" value="#{productListPage.category}" /></f:metadata>

@Named@RequestScopedpublic class ProductListPage {

private String category;

}

Page 32: Beyond PrettyFaces - Einführung in Rewrite

Join mit Parametern

.addRule( Join.path("/products/{category}") .to("/faces/products.xhtml"))

Page 33: Beyond PrettyFaces - Einführung in Rewrite

Demo

Page 34: Beyond PrettyFaces - Einführung in Rewrite

Annotations?

Page 35: Beyond PrettyFaces - Einführung in Rewrite

Einfacher Join

@Named@RequestScoped@Join(path = "/home", to = "/faces/home.xhtml")public class HomePage {

/* your code */

}

Page 36: Beyond PrettyFaces - Einführung in Rewrite

Parameter

/faces/products.xhtml?category=books

/products/books

Page 37: Beyond PrettyFaces - Einführung in Rewrite

Mit View-Parametern@Named@RequestScoped@Join(path = "/products/{category}", to = "/faces/products.xhtml")public class ProductListPage {

// <f:viewParam name=“category“ ...> private String category;

/* ... */

}

Page 38: Beyond PrettyFaces - Einführung in Rewrite

Ohne View-Parameter@Named@RequestScoped@Join(path = "/products/{category}", to = "/faces/products.xhtml")public class ProductListPage {

@Parameter private String category;

/* ... */ }

Page 39: Beyond PrettyFaces - Einführung in Rewrite

Validierung@Named@RequestScoped@Join(path = "/products/{category}", to = "/faces/products.xhtml")public class ProductListPage {

@Parameter @Matches("[a-zA-Z\\-]+") private String category;

/* ... */ }

Page 40: Beyond PrettyFaces - Einführung in Rewrite

JSF Validators@Named@RequestScoped@Join(path = "/products/{category}", to = "/faces/products.xhtml")public class ProductListPage {

@Parameter @Validate(with = CategoryValidator.class) private String category;

/* ... */ }

Page 41: Beyond PrettyFaces - Einführung in Rewrite

Request Actions

Page 42: Beyond PrettyFaces - Einführung in Rewrite

Request Actions@Named@RequestScoped@Join(path = "/home", to = "/faces/home.xhtml")public class HomePage {

@RequestAction public void init() { /* your code */ }

}

Page 43: Beyond PrettyFaces - Einführung in Rewrite

Ignore Postbacks@Named@RequestScoped@Join(path = "/home", to = "/faces/home.xhtml")public class HomePage {

@RequestAction @IgnorePostback public void init() { /* your code */ }

}

Page 44: Beyond PrettyFaces - Einführung in Rewrite

Deferral@Named@ViewScoped@Join(path = "/home", to = "/faces/home.xhtml")public class HomePage {

@RequestAction @Deferred public void init() { /* your code */ }

}

Page 45: Beyond PrettyFaces - Einführung in Rewrite

Deferral@Named@ViewScoped@Join(path = "/home", to = "/faces/home.xhtml")public class HomePage {

@RequestAction @Deferred(before = Phase.RENDER_RESPONSE) public void init() { /* your code */ }

}

Page 46: Beyond PrettyFaces - Einführung in Rewrite

Navigation

Page 47: Beyond PrettyFaces - Einführung in Rewrite

Navigation

<h:link outcome="/products.xhtml"> <f:param name="category" value="books"/> Bücher</h:link>

<a href="/products/books"> Bücher </a>

Page 48: Beyond PrettyFaces - Einführung in Rewrite

Navigation

public class SomePage {

public String actionMethod() {

/* do something */

return "/products.xhtml?category=books" + "&faces-redirect=true";

}

}

Page 49: Beyond PrettyFaces - Einführung in Rewrite

Navigation

public class SomePage {

public Navigate actionMethod() {

/* do something */

return Navigate.to(ProductListPage.class) .with("category", "books");

}

}

Page 50: Beyond PrettyFaces - Einführung in Rewrite

Was kann Rewrite noch?

Page 51: Beyond PrettyFaces - Einführung in Rewrite

Content Delivery Networks(CDN)

Page 52: Beyond PrettyFaces - Einführung in Rewrite

JSF Resources

<h:outputScript name="jquery.js" />

<script type="text/javascript" src="/faces/javax.faces.resource/jquery.js" />

<script type="text/javascript" src="http://dh8sm43.cloudfront.net/jquery.js" />

Erzeugt

Gewünscht

Page 53: Beyond PrettyFaces - Einführung in Rewrite

CDN URL Relocation

.addRule( CDN.relocate("/faces/javax.faces.resource/jquery.js") .to("http://dh8sm43.cloudfront.net/jquery.js"))

Page 54: Beyond PrettyFaces - Einführung in Rewrite

ResourceTransformation

Page 55: Beyond PrettyFaces - Einführung in Rewrite

HTTP Response

RewriteTransformation

Pipeline

Page 56: Beyond PrettyFaces - Einführung in Rewrite

Usecases

• Minification – JavaScript, CSS

• Compression – GZIP, Deflate

• Rendering – SASS, SCSS, Markdown, Textile, ...

• Custom Processing

Page 57: Beyond PrettyFaces - Einführung in Rewrite

JavaScript Minify

.addRule()

.when( Direction.isInbound().and(Path.matches( "/faces/javax.faces.resource/{*}.js"))).perform( Transform.with(Minify.js()))

Page 58: Beyond PrettyFaces - Einführung in Rewrite

Rendering

Page 59: Beyond PrettyFaces - Einführung in Rewrite

Beispiel: Sass$blue: #3bbfce;$margin: 16px;

.content-navigation { border-color: $blue; color: darken($blue, 9%);}

.border { padding: $margin / 2; margin: $margin / 2; border-color: $blue;}

.content-navigation { border-color: #3bbfce; color: #2b9eab;}

.border { padding: 8px; margin: 8px; border-color: #3bbfce;}

Page 60: Beyond PrettyFaces - Einführung in Rewrite

Beispiel: Sass

.addRule()

.when( Direction.isInbound().and( Path.matches("/styles/{*}.sass"))).perform( Response.setContentType("text/css").and( Transform.with(Sass.compiler())))

Page 61: Beyond PrettyFaces - Einführung in Rewrite

Precompile with Maven

<plugin> <groupId>org.jasig.maven</groupId> <artifactId>sass-maven-plugin</artifactId> <version>1.1.1</version> <executions> <execution> <phase>prepare-package</phase> <goals> <goal>update-stylesheets</goal> </goals> </execution> </executions></plugin>

Page 62: Beyond PrettyFaces - Einführung in Rewrite

Transform on demand.addRule().when( Direction.isInbound() .and(Path.matches("/styles/{name}.css")) .and(Resource.exists("/styles/{name}.scss")) .and(Not.any( Resource.exists("/styles/{name}.css")))).perform( Forward.to("/styles/{name}.scss") .and(Response.setContentType("text/css")) .and(Transform.with(Sass.compiler())))

Page 63: Beyond PrettyFaces - Einführung in Rewrite

Wie migriere ich meine PrettyFaces Anwendung?

Page 64: Beyond PrettyFaces - Einführung in Rewrite

Rewrite PrettyFaces Module

<dependency> <groupId>org.ocpsoft.rewrite</groupId> <artifactId>rewrite-config-prettyfaces</artifactId> <version>2.0.8.Final</version></dependency>

• Drop-In Replacement für PrettyFaces• „Sanfte“ Migration

Page 65: Beyond PrettyFaces - Einführung in Rewrite

Thank you!

http://ocpsoft.org/rewrite/

Christian [email protected] @chkal