Java EE is already the perfect solution for complex business/enterprise systems, and the improvements in JavaServer Faces 2.x provide the perfect chance to reach out to the consumer and small business market; JSF is easier to use than it's ever been before, now making it accessible to businesses of all sizes. In order to complete the user-experience, however, one must not overlook the URL. How PrettyFaces works: The talk introduces you to URL rewriting, storing contextual information – safely – and managing page configuration data with address and query parameters. PrettyFaces’ centralized approach uses URLs to retain the state of pages, meaning less information must be stored in session and application scoped beans. Rethinking navigation: Navigation from the eye of the client. JSF supports page flows well, but managing simple transitions from one page to another can be complex. Examples of PrettyFaces integrated navigation, hyper-linking via Bijection and Components will show how developers gain increased control over all aspects of navigation out of the box, and how this is accomplished without extra configuration. SEO: You will be presented with brief concepts of how to improve client experience, search rank, and conversions through URL parameterization and linking – the importance the browser URL plays an in establishing trust through all client interactions. Examples & Community: What better to wrap up a presentation other than real examples of how to use and tie together what you’ve learned? A few short demos will be followed up with a brief summary of what’s coming up in the URL-rewriting community, how new advancements will benefit everyone, and what we can all do to keep advancement coming.
2. PrettyFaces
Simplified JSF Navigation,
Actions, and URL-rewriting.
Lincoln Baxter III
http://ocpsoft.com
3. #jaxconf #prettyfaces
( At this time, the audience
is encouraged to use PDAs,
cell phones, and other
portable electronic
devices... )
Lincoln Baxter III
http://ocpsoft.com
4. My Life Story.
yawn...
Lincoln Baxter III
http://ocpsoft.com
8. URL-rewriting.
wtf?
Lincoln Baxter III
http://ocpsoft.com
9. “A URL rewriting extension for Servlet containers,
Java EE, with optional tight-integration for JSF and
other frameworks.”
Lincoln Baxter III
http://ocpsoft.com
21. Initially
a bookmarking extension for JSF 1.2
Grown
a feature-rich URL-rewriting solution
Evolved
supports pure Servlet and Java EE
Future
a JSR for URL-rewriting in Java EE
Lincoln Baxter III
http://ocpsoft.com
22. Life is good.
:) but...
Lincoln Baxter III
http://ocpsoft.com
23. Why Pretty URLs?
•Build trust
•Enhance user experience
•Self-promote
Lincoln Baxter III
http://ocpsoft.com
24. / PrettyFaces
/ background
/ basics
/ navigation
/ demos
/ wrap-up
Lincoln Baxter III
http://ocpsoft.com
25. The Basics.
Lincoln Baxter III
http://ocpsoft.com
28. Build trust by reducing clutter.
Before:
http://example.com/news.xhtml?p=my-new-post
After:
http://example.com/news/my-new-post/
Lincoln Baxter III
http://ocpsoft.com
29. Vulnerable!
wtf?
Real-life: wtf?
http://www.llbean.com/webapp/wcs/stores/servlet/CategoryDispl
ay?categoryId=28&storeId=1&catalogId=1&langId=-
1&nav=hp-gndp
Cluttered! Lincoln Baxter III
http://ocpsoft.com
30. Should have been:
http://llbean.com/kids
Lincoln Baxter III
http://ocpsoft.com
31. <url-mapping>
<pattern value=”/kids” />
<view-id value=”/webapp/wcs/stores/servlet/CategoryDisplay?categoryId=28“ />
</url-mapping>
Lincoln Baxter III
http://ocpsoft.com
32. $$$$!!!
or... $#@!
A fictitious, malicious example:
http://acme.com/store
& catCode=ZfSd41
& lang=en_US
& account=lincolnthree
& autoLoginCd=S3fds94Zd03
& oneClickPurchase=true
& item=veryExpensive
& redirectAfter=www.google.com?q=Have+a+nice+day+sucker!
Lincoln Baxter III
http://ocpsoft.com
33. Clean that URL.
Why do you think people are afraid of buying
used cars?
Lincoln Baxter III
http://ocpsoft.com
41. / root / the / user
•Be consistent, always.
•Be general, progress to specific.
•Think hard about using a query string.
Lincoln Baxter III
http://ocpsoft.com
42. The URL and p14n are:
•Where you are, what you're looking at.
•In the “request” scope; relevant.
•User accessible!
Lincoln Baxter III
http://ocpsoft.com
43. Examples:
Good :)
http://example.com/store
http://example.com/store/item/12
http://example.com/store/item/12/reviews
http://example.com/store/item/12/reviews/34
Bad :(
http://example.com/store/12/reviews/23/item
Lincoln Baxter III
http://ocpsoft.com
44. Problem solved.
- PrettyFaces -
Lincoln Baxter III
http://ocpsoft.com
45. Inject directly.
<url-mapping>
<pattern value=”/store/item/#{ itemBean.number }” />
<view-id value=”/faces/item.xhtml“ >
</url-mapping>
Lincoln Baxter III
http://ocpsoft.com
46. Add a request parameter.
item.xhtml?number=#{...}
<url-mapping>
<pattern value=”/store/item/#{ number }” />
<view-id value=”/faces/item.xhtml” />
</url-mapping>
Lincoln Baxter III
http://ocpsoft.com
47. Both.
<url-mapping>
<pattern value=”/store/item/#{ number : itemBean.number }” />
<view-id value=”/faces/item.xhtml” />
</url-mapping>
Lincoln Baxter III
http://ocpsoft.com
51. Nothing fancy.
<url-mapping>
<pattern value=”/store/item/#{itemBean.number}” />
<view-id value=”/faces/store/view.xhtml” />
<action> #{ currentProjectBean.load } </action>
</url-mapping>
Lincoln Baxter III
http://ocpsoft.com
52. You decide.
<url-mapping>
<pattern value=”/store/item/#{itemBean.number}” />
<view-id value=”/faces/store/view.xhtml” />
<action phaseId=”RENDER_RESPONSE”>
#{ currentProjectBean.load }
</action>
</url-mapping>
Lincoln Baxter III
http://ocpsoft.com
53. Alternatives.
More Configuration
2.0 view Url Rewrite 2.0 event 1.x: requires
params Filter listeners seam or other
Lines: +3 +8 +1+n +4
= ~17!
PrettyFaces
pretty-config.xml
= ~4 :)
Lincoln Baxter III
http://ocpsoft.com
54. Annotations
@Named
@RequestScoped
@URLMapping(
id = "barcode",
pattern = "/#{ /[0-9]+/ barcodeBean.value }.png",
viewId = "/barcode.jsf")
public class BarcodeBean
{
private String value;
@URLAction(phaseId=PhaseId.RENDER_RESPONSE)
public void load() throws IOException
{
// do the work
}
}
Lincoln Baxter III
http://ocpsoft.com
55. SeamFaces @ViewConfig
@ViewConfig
public interface MyAppViewConfig {
static enum Pages {
@ViewPattern("/admin.xhtml")
@Admin
ADMIN,
@ViewPattern("/item.xhtml")
@UrlMapping(pattern="/item/#{id}/")
@Owner
ITEM,
@ViewPattern("/*")
@FacesRedirect
@AccessDeniedView("/denied.xhtml")
@LoginView("/login.xhtml")
ALL;
}
}
Lincoln Baxter III
http://ocpsoft.com
57. The Basics.
•Clean that URL! - build trust, self promote.
•Parameterize logically, in order – root the user
•Load data declaratively (Validate everything)
•You choose the configuration!
Lincoln Baxter III
http://ocpsoft.com
58. / PrettyFaces
/ background
/ basics
/ navigation
/ demos
/ wrap-up
Lincoln Baxter III
http://ocpsoft.com
59. History, the old
school, JSF 1.x.
Lincoln Baxter III
http://ocpsoft.com
64. That Same Configuration.
The Mapping ID:
<url-mapping id=”viewStore”>
<pattern value=”/store/item/#{ item : itemBean.number }” />
<view-id value=”/faces/item.xhtml” />
</url-mapping>
<pretty:link mappingId=”viewStore”>
<f:param value=”prettyfaces”/>
</pretty:link>
Renders: /store/item/prettyfaces
Lincoln Baxter III
http://ocpsoft.com
65. Go where you want.
private String createItem()
{
if(dao.createItem(newitem))
{
itemBean.setItem(newitem.getId());
return “pretty:viewItem”;
}
FacesUtils.addError(“Something went wrong! Try again.”);
return “pretty:”;
}
Lincoln Baxter III
http://ocpsoft.com
66. Take only what you need.
from me
Lincoln Baxter III
http://ocpsoft.com
67. Or... do “nothing.”
•Write a normal Java EE / JSF 2.0 application.
•Add PrettyFaces outbound URL-rewriting.
•Request-parameter mapping #{name} is power.
Lincoln Baxter III
http://ocpsoft.com
70. In summary.
•You do not need to use pretty-navigation or links.
•But they're there if you want them
•PrettyFaces is non-invasive... seriously.
Lincoln Baxter III
http://ocpsoft.com
71. And I'll prove it...
Lincoln Baxter III
http://ocpsoft.com
72. / PrettyFaces
/ background
/ basics
/ navigation
/ demos
/ wrap-up
Lincoln Baxter III
http://ocpsoft.com
73. Awesome demos!
Yayayayayay!!!
Lincoln Baxter III
http://ocpsoft.com
74. / PrettyFaces
/ background
/ basics
/ navigation
/ demos ? plan for
change=true
/ wrap-up
Lincoln Baxter III
http://ocpsoft.com
77. / PrettyFaces
/ background
/ basics
/ navigation
/ demos
/ wrap-up
Lincoln Baxter III
http://ocpsoft.com
78. PrettyFaces in two minutes.
“A masterpiece.” ~non-fictional user.
Lincoln Baxter III
http://ocpsoft.com
79. Add PrettyFaces
via Maven.
<dependency>
<groupId>com.ocpsoft</groupId>
<artifactId>prettyfaces-jsf2</artifactId>
<version>${most-recent-version}</version>
</dependency>
Yeah this works with pure Servlets,
too. I know...
Lincoln Baxter III
http://ocpsoft.com
80. Add PrettyFaces
via Seam Forge.
$ forge git-plugin
git://github.com/ocpsoft/prettyfaces-forge-plugin.git
$ setup prettyfaces
$ prettyfaces mapping –pattern {...} --resource {...}
Lincoln Baxter III
http://ocpsoft.com
82. Make it work.
Take action ;)
<pretty-config>
<!-- Begin Mappings -->
<url-mapping id="home">
<pattern value="/home" />
<view-id value="/faces/home.jsf”>
<action> #{homeBean.loadUserLayout} </action>
</url-mapping>
<url-mapping id="viewComment">
<pattern value="/story/#{myBean.currentStoryId}/#{myBean.commentId}" />
<view-id value="/faces/story/comment.jsf” />
</url-mapping>
</pretty-config>
Lincoln Baxter III
http://ocpsoft.com
83. Navigate.
../viewComment.jsf
<html xmlns:pretty="http://ocpsoft.com/prettyfaces" >
<pretty:link mappingId="comment">
<f:param value="23" />
<f:param value="5" />
Go to Comment. (This is Link Text)
</pretty:link>
<h:link outcome="pretty:comment">
<f:param name="sid" value="#{myBean.storyId}" />
<f:param name="cid" value="#{myBean.nextCommentId}" />
View next comment. (This is Link Text)
</h:link>
Lincoln Baxter III
http://ocpsoft.com
84. The Site-map.
If this presentation were a website...
<pretty-config>
<url-mapping id="home">
<pattern value=”/prettyfaces” />
<view-id value=”faces/home.jsf” />
</url-mapping>
<url-mapping id="levelOne">
<pattern value=”/prettyfaces/#{presBean.levelOne}” />
<view-id value=”/faces/present.jsf” />
</url-mapping>
<url-mapping id="levelTwo">
<pattern value=”/prettyfaces/#{presBean.levelOne}/#{presBean.levelTwo}” />
<view-id value=”/faces/present.jsf” />
</url-mapping>
</pretty-config>
Lincoln Baxter III
http://ocpsoft.com
85. / PrettyFaces
/ background
/ basics
/ navigation
/ demo
/ wrap-up
Lincoln Baxter III
http://ocpsoft.com
86. PrettyFaces is...
●
URL-rewriting
●
URL-parameterization
●
Action-framework for JSF (Servlet soon)
●
Navigation framework for JSF (Servlet soon)
●
Extendable, configurable (SPI is growing!)
●
Waiting for your ideas!
Lincoln Baxter III
http://ocpsoft.com
87. Get Involved!
Get Started
http://ocpsoft.com/prettyfaces/
Get Help
http://ocpsoft.com/support/
Get the code!
http://github.com/ocpsoft/prettyfaces
Lincoln Baxter III
http://ocpsoft.com