Set URL to dynamic URL in JSF [duplicate] - jsf

For example, I have class Article with methods getTitle () and getContent ().
I also have ArticlesService with method getAllArticles (). How to create a list of links with meaningful names (formed with #{article.title})? Like:
http://mysiteaddress.com/article/first-article-title
http://mysiteaddress.com/article/how-to-make-links-in-jsf
..or something similar.
I can create links with all necessary functionality with <h:commandLink>, but I don't know how to make nice 'href' for it: it always has href '#'.
I can create nice links with <h:outputLink> but I don't know how to add necessary functionality to it.
In jsp I created my own front-controller, which parsed urls from requests and then performed redirection to correspondent jsp-page.
How to achieve the same functionality in JSF?

If this is intended as an improvement of an existing application, then you basically need a Filter which detects "dirty" and "friendly" URLs. When it detects a "dirty" URL, then it should redirect the request to a "friendly" URL by HttpServletResponse#sendRedirect(). When it detects a "friendly" URL, then it should forward the request to the "dirty" URL by RequestDispatcher#forward(). An example can be found in this related question: How to use a servlet filter in Java to change an incoming servlet request url?
Further, you also need a custom ViewHandler to produce the desired "friendly" URL for JSF <h:form>, <h:link>, etc. An example can be found here: Dynamic Directory in Java EE Web Application.
If this is a new application or an application which is open to changes, you could consider any of the existing pretty URL libraries instead of reinventing the wheel:
PrettyFaces, which is a complete URL rewrite solution. It requires an additional XML configuration file pretty-config.xml. This library is useful if you want to completely change URLs and/or want to configure redirects from old to new URLs.
FacesViews of OmniFaces library, which makes existing URLs just extensionless by a single web.xml context param. It also supports "MultiViews" whereby path parameters can declaratively be injected in managed beans. E.g. /foo/bar/baz can point to /foo.xhtml and the values bar and baz can be injected by #Param(pathIndex).
There's also the experimental PrettyUrlPhaseListener of Mojarra Scales library, but it's an old library and PrettyFaces is largely based on it, so it's not worth the effort.

Did you tried PrettyFaces?
Simple, effective, bookmark, JSF
PrettyFaces is an OpenSource extension for JSF1.2 and JSF2.0, which enables creation of bookmark-able, pretty URLs. PrettyFaces solves this problem elegantly, including features such as: page-load actions, seamless integration with faces navigation, dynamic view-id assignment, managed parameter parsing, and configuration-free compatibility with other JSF frameworks.
SEO and Consistency:
Any business knows how important Search Engine Optimization can be for sales. PrettyFaces allows SEO-friendly URLs, and improved customer experience. Give your site a uniform, well understood feeling, from the address bar to the buy button.

Related

JSF - How to migrate URLs by intercepting and redirecting potential 404 errors?

When migrating websites often dead URLs happen since old website used different URL structure or technology. Correct 301 "permanent" redirect is important for SEO friendly migrations.
Example:
Old page https://example.com/product/coca-cola-bottle.html moved in our JSF project to https://example.com/p/coca-cola-1-l/1000
Concept
We will save those mappings in our database and add them to our JSF application.
If an URL is requested that is not valid or rewritten we want to check the current requested URL if it exists in our database and redirect to the new target.
Some Ideas?
Create a custom exception handler and redirect if resource was not found
Override navigation handler to handle it before exception handler
Use #WebFilter with DispatcherType.ERROR and 404 error code check
Use OCPSoft rewrite solution. Not sure how to do this without loading all mappings into configuration. I prefer dynamic (lazy) approach.
Right now i implemented #WebFilter version using an injected bean to lookup the mapping.
I would start by including the rewrite-integration-cdi module:
https://github.com/ocpsoft/rewrite/blob/master/documentation/src/main/asciidoc/integration/cdi.asciidoc
Then create a CDI bean/Java class that can access your database.
Inject an instance of that class into your Rewrite ConfigurationProvider, then use it to build / create your Rewrite rules.
Here is an example of both #Injecting beans into your ConfigurationProvider, and also defining custom HTTP operations:
https://github.com/ocpsoft/rewrite/blob/master/showcase/rest-ws/src/main/java/org/ocpsoft/rewrite/showcase/rest/RestRewriteConfiguration.java
Depending on how dynamic you want your database lookups to be, you could either preload them at startup time (when the Config is built), or load & cache them inside the Request/Response lifecycle itself using a custom HttpCondition and `HttpOperation:
https://github.com/ocpsoft/rewrite/blob/master/api-servlet/src/main/java/org/ocpsoft/rewrite/servlet/config/HttpCondition.java
https://github.com/ocpsoft/rewrite/blob/master/api-servlet/src/main/java/org/ocpsoft/rewrite/servlet/config/HttpOperation.java
Then use those operations in your ConfigurationProvider to perform the database operations. Essentially you will do something like this, but check the database to see if the requested URL is a ‘known/stored’ redirect:
https://github.com/ocpsoft/rewrite/blob/851ccbabb8b6248c66589076fa67cb0ec07b3132/impl-servlet-tests/src/test/java/org/ocpsoft/rewrite/servlet/config/HttpRequestParameterTestProvider.java#L45
And then use an custom HttpOperation to perform the actions you want to take.
https://github.com/ocpsoft/rewrite/blob/851ccbabb8b6248c66589076fa67cb0ec07b3132/config-servlet/src/test/java/org/ocpsoft/rewrite/servlet/config/JoinBindingConfigurationProvider.java#L48
You could also technically just use a Condition that matches all requests, and an HttpOperation That only takes action if there is a database entry.
All that said, this sounds more complicated than it is, but there’s no good example I can find to link to that does exactly what you want, so I’m trying to piece it together.

Tuckey UrlRewrite filter doesn't work properly with JSF forms

I integrated Tuckey UrlRewrite filter in my JSF application. My URLs now look like:
http://localhost:8080/myapp/page
instead of
http://localhost:8080/myapp/faces/page.xhtml
The problem is that my JSF forms submits to the old url
http://localhost:8080/myapp/faces/page.xhtml
and I am getting a FacesFileNotFoundException.
How can I solve this issue?
You've to implement a custom ViewHandler and override the getActionURL() method to return the desired form action URL. That's where the forms get its action URL from. This is by the way also what PrettyFaces, the JSF URL rewrite solution, does. You may want to use it instead of reinventing the same wheel. It's by the way open source, so you could just peek around in its source code to see how they did it.

JSF 2.0 : change default behaviour from page forward to page redirect

I know there are some advantages in using page forwarding as it is the default in JSF.
I also know how to set redirect for some pages using 'faces-redirect' in the implicit navigation or the tag in the faces-config file.
I searched a lot on internet but I didn't find an easy and straight way (such as a configuration parameter) to enable redirect for all pages.
The reason I would like to use page redirect everywhere is the following: if every page is asked whit its url the container can be used for page authorization without the need of additional security library. Don't know if it can be a good idea, but performances are not an issue in this moment and using container security can save development time for the first release.
You can achieve this with a custom ConfigureableNavigationHandler. You can find a kickoff example in the answer to this question: JSF 2 and Post/Redirect/Get?
However, I have the feeling that you're designing page-to-page navigation the wrong way. You seem to be using POST requests for simple page-to-page navigation. If you fix them to be GET requests, then you don't need to worry about this. So, use <h:link> instead of <h:commandLink> for page-to-page navigation. This way you don't need to implement the PRG. See also When should I use h:outputLink instead of h:commandLink?

How to create addressable pages using JSF

Using the currrent version of Java EE, how do you create addressable web pages using Java Server Faces (JSF). That is, creating JSF pages that have a clean URL, so the page for the person entity with ID 1234 might be http://www.example.com/person/1234? It's clear enough to me how to service a clean URL using the Java API for RESTful web services (JAX-RS), but not how to do so for a JSF page, or how to combine the two.
A previous question I found suggests that doing so is not actually possible. Is that really so?
Use a URL rewriting solution like PrettyFaces. It uses basically a simple Filter under the covers which forwards the request from pretty to ugly URL and redirects the request from ugly to pretty URL based on some XML mapping file.
Related questions:
Bookmarkable URL in JSF application - Trying to use Spring Webflow and JSF . Any suggestions?
How to rewrite the URL
How do I configure JSF url mappings without file extensions?

how to create a link to a JSF page from outside the application

I am working with a JSF application that posts on every mouse click, so if you get 5 pages deep, your url stays the same.
now i need to link to one of these pages from outside of jsf. what can i do?
(i am new to jsf)
Navigation rules use forward by default, that's why the URL does not change.
Use http://site.com/ctx/page.jsf to access a given page. *.jsf is the mapping of your faces servlet to in web.xml (it can have different value in your configuration, but normally it is *.jsf or /faces/*
i dont know if ive got it right but as much as i understood it you need to use GET instead of POST this time, right?
in my current project we still use JSF 1.2 and that is achieved by PrettyFaces (http://ocpsoft.com/prettyfaces/) by us. do you mean that?

Resources