prettyfaces: simplified jsf navigation, actions, and url-rewriting: lincoln baxter iii
Post on 17-May-2015
3.381 Views
Preview:
DESCRIPTION
TRANSCRIPT
Lincoln Baxter IIIhttp://ocpsoft.com
PrettyFacesSimplified JSF Navigation, Actions, and URL-rewriting.
Lincoln Baxter IIIhttp://ocpsoft.com
( At this time, the audience is encouraged to use PDAs, cell phones, and other portable electronic devices... )
#jaxconf #prettyfaces
Lincoln Baxter IIIhttp://ocpsoft.com
/ PrettyFaces/ background/ basics/ navigation
/ demos/ wrap-up
Lincoln Baxter IIIhttp://ocpsoft.com
“A URL rewriting extension for Servlet containers, Java EE, with optional tight-integration for JSF and
other frameworks.”
Lincoln Baxter IIIhttp://ocpsoft.com
http://example.com/faces/store.jsf
http://example.com/store
Lincoln Baxter IIIhttp://ocpsoft.com
http://example.com/faces/item.xhtml?item=Z34SD498
http://example.com/store/item/Z34SD498
Lincoln Baxter IIIhttp://ocpsoft.com
/ PrettyFaces/ background/ basics/ navigation
/ demos/ wrap-up
Lincoln Baxter IIIhttp://ocpsoft.com
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 IIIhttp://ocpsoft.com
Why Pretty URLs?
•Build trust
•Enhance user experience
•Self-promote
Lincoln Baxter IIIhttp://ocpsoft.com
/ PrettyFaces/ background/ basics/ navigation
/ demos/ wrap-up
Lincoln Baxter IIIhttp://ocpsoft.com
/ PrettyFaces/ background/ basics/ navigation
/ demos/ wrap-up
/ clean/ parameterize/ load
Lincoln Baxter IIIhttp://ocpsoft.com
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 IIIhttp://ocpsoft.com
http://www.llbean.com/webapp/wcs/stores/servlet/CategoryDisplay?categoryId=28&storeId=1&catalogId=1&langId=-1&nav=hp-gndp
http://www.llbean.com/webapp/wcs/stores/servlet/CategoryDisplay?categoryId=28&storeId=1&catalogId=1&langId=-1&nav=hp-gndp
Vulnerable!
Cluttered!
Real-life:wtf?
wtf?
Lincoln Baxter IIIhttp://ocpsoft.com
Should have been:
http://llbean.com/kids
Lincoln Baxter IIIhttp://ocpsoft.com
<url-mapping><pattern value=”/kids” /><view-id value=”/webapp/wcs/stores/servlet/CategoryDisplay?categoryId=28“ />
</url-mapping>
Lincoln Baxter IIIhttp://ocpsoft.com
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!
$$$$!!! or... $#@!
Lincoln Baxter IIIhttp://ocpsoft.com
Clean that URL.Why do you think people are afraid of buying used cars?
Lincoln Baxter IIIhttp://ocpsoft.com
http://www.youtube.com/watch?v=dQw4w9WgXcQ
Trust Me?
Lincoln Baxter IIIhttp://ocpsoft.com
http://www.linkedin.com/in/lincolnthreehttp://twitter.com/lincolnthree http://ocpsoft.com/prettyfaces/
Trust Me.
Lincoln Baxter IIIhttp://ocpsoft.com
A clean, readable URL:
•Builds trust
•Is self-promoting, benefits SEO
•Reduces vulnerability
Lincoln Baxter IIIhttp://ocpsoft.com
/ PrettyFaces/ background/ basics/ navigation
/ demos/ wrap-up
/ clean/ parameterize/ load
Lincoln Baxter IIIhttp://ocpsoft.com
/ root / the / user
•Be consistent, always.
•Be general, progress to specific.
•Think hard about using a query string.
Lincoln Baxter IIIhttp://ocpsoft.com
•Where you are, what you're looking at.
•In the “request” scope; relevant.
•User accessible!
The URL and p14n are:
Lincoln Baxter IIIhttp://ocpsoft.com
http://example.com/storehttp://example.com/store/item/12http://example.com/store/item/12/reviewshttp://example.com/store/item/12/reviews/34
Bad :(http://example.com/store/12/reviews/23/item
Examples:
Good :)
Lincoln Baxter IIIhttp://ocpsoft.com
<url-mapping><pattern value=”/store/item/#{ itemBean.number }” /><view-id value=”/faces/item.xhtml“ >
</url-mapping>
Inject directly.
Lincoln Baxter IIIhttp://ocpsoft.com
<url-mapping><pattern value=”/store/item/#{ number }” /><view-id value=”/faces/item.xhtml” />
</url-mapping>
Add a request parameter.
item.xhtml?number=#{...}
Lincoln Baxter IIIhttp://ocpsoft.com
<url-mapping><pattern value=”/store/item/#{ number : itemBean.number }” /><view-id value=”/faces/item.xhtml” />
</url-mapping>
Both.
Lincoln Baxter IIIhttp://ocpsoft.com
/ PrettyFaces/ background/ basics/ navigation
/ demos/ wrap-up
/ clean/ parameterize/ load
Lincoln Baxter IIIhttp://ocpsoft.com
Loading your data.
•Eagerly (On construction)
•Lazily (On access)
•Declaratively (On event, or request)
Lincoln Baxter IIIhttp://ocpsoft.com
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 IIIhttp://ocpsoft.com
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 IIIhttp://ocpsoft.com
Alternatives.
2.0 viewparams
Url RewriteFilter
2.0 eventlisteners
1.x: requiresseam or other
More Configuration
+3 +8 +1+n +4Lines:
pretty-config.xml
= ~4 :)
PrettyFaces
= ~17!
Lincoln Baxter IIIhttp://ocpsoft.com
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 IIIhttp://ocpsoft.com
@ViewConfigpublic 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; }}
SeamFaces @ViewConfig
Lincoln Baxter IIIhttp://ocpsoft.com
Your own source!
com.ocpsoft.pretty.faces.spi.ConfigurationProvider
Lincoln Baxter IIIhttp://ocpsoft.com
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 IIIhttp://ocpsoft.com
/ PrettyFaces/ background/ basics/ navigation
/ demos/ wrap-up
Lincoln Baxter IIIhttp://ocpsoft.com
<navigation-rule> <from-view-id> * </from-view-id> <navigation-case> <from-action> * </from-action> <from-outcome> viewStore </from-outcome> <to-view-id> /faces/store/view.xhtml </to-view-id> <redirect /> </navigation-case></navigation-rule>
<h:commandLink action=”viewStore” value=”Go to store> <f:setPropertyActionListener target=”#{itemBean.name}” value=”prettyfaces” /></h:commandLink>
Lincoln Baxter IIIhttp://ocpsoft.com
<h:link action=”/faces/item.xhtml”> <f:param name=”item” value=”prettyfaces”/></h:link>
<f:metadata> <f:viewParam name=”item” value=”#{itemBean.number}” /></f:metadata>
Lincoln Baxter IIIhttp://ocpsoft.com
That Same Configuration.
<url-mapping id=”viewStore”><pattern value=”/store/item/#{ item : itemBean.number }” /><view-id value=”/faces/item.xhtml” />
</url-mapping>
The Mapping ID:
<pretty:link mappingId=”viewStore”> <f:param value=”prettyfaces”/></pretty:link>
Renders: /store/item/prettyfaces
Lincoln Baxter IIIhttp://ocpsoft.com
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 IIIhttp://ocpsoft.com
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 IIIhttp://ocpsoft.com
Look familiar?
<h:link outcome=”/item.xhtml”> <f:param name=”item” value=”prettyfaces”/></h:link>
Renders: /store/item/prettyfaces
Lincoln Baxter IIIhttp://ocpsoft.com
<url-mapping id=”viewStore”><pattern value=”/item/#{ item }” /><view-id value=”/faces/item.xhtml” />
</url-mapping>
http://example.com/store/item/23
http://example.com/faces/item.xhtml ? item=23
inbound outbound
Lincoln Baxter IIIhttp://ocpsoft.com
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 IIIhttp://ocpsoft.com
/ PrettyFaces/ background/ basics/ navigation
/ demos/ wrap-up
Lincoln Baxter IIIhttp://ocpsoft.com
/ PrettyFaces/ background/ basics/ navigation
/ demos ? plan for change=true
/ wrap-up
Lincoln Baxter IIIhttp://ocpsoft.com
/ PrettyFaces/ background/ basics/ navigation
/ demos/ wrap-up
Lincoln Baxter IIIhttp://ocpsoft.com
PrettyFaces in two minutes.“A masterpiece.” ~non-fictional user.
Lincoln Baxter IIIhttp://ocpsoft.com
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 IIIhttp://ocpsoft.com
Add PrettyFaces
via Seam Forge.
$ forge git-plugin git://github.com/ocpsoft/prettyfaces-forge-plugin.git
$ setup prettyfaces
$ prettyfaces mapping –pattern {...} --resource {...}
Lincoln Baxter IIIhttp://ocpsoft.com
Map something.
Create /WEB-INF/pretty-config.xml
<pretty-config>
<!-- Begin Mappings --> <url-mapping id="home"> <pattern value="/home" /> <view-id value="/faces/home.jsf" > </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 IIIhttp://ocpsoft.com
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 IIIhttp://ocpsoft.com
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 IIIhttp://ocpsoft.com
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 IIIhttp://ocpsoft.com
/ PrettyFaces/ background/ basics/ navigation
/ demo/ wrap-up
Lincoln Baxter IIIhttp://ocpsoft.com
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 IIIhttp://ocpsoft.com
Get Involved!
Get Started
http://ocpsoft.com/prettyfaces/
Get Help
http://ocpsoft.com/support/
Get the code!
http://github.com/ocpsoft/prettyfaces
Lincoln Baxter IIIhttp://ocpsoft.com
PrettyFaces is...
“Beautiful Java EE: URL-rewriting for the next generation web-user”
Lincoln Baxter IIIhttp://ocpsoft.com
Questions.I've been talking for nearly an hour; please,
somebody say something.
“wtf?”
top related