How to call to get the source page which requets another JSF page - jsf

I want to know how to get the name of the page that requests another JSF page to further call specific methods in the bean according to the source page, i don't want to use <f:event type="preRenderView"
listener="#{beanName.preRender}" /> because the specified page has components that's rendered according to the source page

AS far as I know this has to be handcoded and the best way to do it is probably in a #WebFilter. and request.getRequestURI();
Then simply save the pages in a suitible fashion for example ArrayDeque.
The ArrayDeque could for example be saved in a #SessionScoped bean.

Related

jsf page navigation best practices [duplicate]

When should I use an <h:outputLink> instead of an <h:commandLink>?
I understand that a commandLink generates an HTTP post; I'm guessing that outputLink will generate HTTP gets. That said, most of the JSF tutorial material I've read uses commandLink (almost?) exclusively.
Context: I am implementing a wee little demo project that shows a header link to a user page, much like Stack Overflow's...
...and I am not sure if commandLink (perhaps using ?faces-redirect=true for bookmarkability) or outputLink is the right choice.
The <h:outputLink> renders a fullworthy HTML <a> element with the proper URL in the href attribute which fires a bookmarkable GET request. It cannot directly invoke a managed bean action method.
<h:outputLink value="destination.xhtml">link text</h:outputLink>
The <h:commandLink> renders a HTML <a> element with an onclick script which submits a (hidden) POST form and can invoke a managed bean action method. It's also required to be placed inside a <h:form>.
<h:form>
<h:commandLink value="link text" action="destination" />
</h:form>
The ?faces-redirect=true parameter on the <h:commandLink>, which triggers a redirect after the POST (as per the Post-Redirect-Get pattern), only improves bookmarkability of the target page when the link is actually clicked (the URL won't be "one behind" anymore), but it doesn't change the href of the <a> element to be a fullworthy URL. It still remains #.
<h:form>
<h:commandLink value="link text" action="destination?faces-redirect=true" />
</h:form>
Since JSF 2.0, there's also the <h:link> which can take a view ID (a navigation case outcome) instead of an URL. It will generate a HTML <a> element as well with the proper URL in href.
<h:link value="link text" outcome="destination" />
So, if it's for pure and bookmarkable page-to-page navigation like the SO username link, then use <h:outputLink> or <h:link>. That's also better for SEO since bots usually doesn't cipher POST forms nor JS code. Also, UX will be improved as the pages are now bookmarkable and the URL is not "one behind" anymore.
When necessary, you can do the preprocessing job in the constructor or #PostConstruct of a #RequestScoped or #ViewScoped #ManagedBean which is attached to the destination page in question. You can make use of #ManagedProperty or <f:viewParam> to set GET parameters as bean properties.
See also:
ViewParam vs #ManagedProperty(value = "#{param.id}")
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
Bookmarkability via View Parameters feature
How to navigate in JSF? How to make URL reflect current page (and not previous one)
I also see that the page loading (performance) takes a long time on using h:commandLink than h:link. h:link is faster compared to h:commandLink

PrimeFaces datatable.filter() and url parameter

I have a .xhtml model with a primeface datatable in it.
I call the page with an URL like this:
http://localhost:8080/myproject/mypage.jsf?Id=51&startDate=04-05-2015&name=whatever
The URL parameters are used to retrieve what will be displayed in the datatable, so it allow me to filter the content.
I used URL parameter because this page is displayed when I select a row in another datable so I have to make a manual redirect to this page on the baking bean.
However everytime I use one of primeface functionality like sorting or pagination primeface seems to do an ajax call to the backing bean but WITHOUT the parameters, so every object are displayed instead of a filtered list of Objects.
Therefore how can I force primefaces to use these parameters? Or how can I pass them to primefaces scope (they are #ManagedProperty on the backing bean)
The best and easiest way is to use the OmniFaces utility library and more specifically their <o:form>.
From the documentation:
The <o:form> is a component that extends the standard <h:form> and provides a way to keep view or request parameters in the request URL after a post-back
...
You can use it the same way as <h:form>, you only need to change h: to o:.
So, replace your <h:form> by either
<o:form includeRequestParams="true">
or
<o:form useRequestURI="true">
See also:
Retaining GET request query string parameters on JSF form submit

Get url parameter into facelets view after user session timeout

I am building a CRUD web application using JSF. I have a problem with loading a page after the user session has timed out. That is i lose the parameters I need to construct the view (even though the parameters are still visible in the url like so: 'someurl/view.xhtml?pid=5'.
In the .xhtml file the parameter pid is used to load some content from an underlying database when constructing the view. When the user has been inactive for a while their session times out, and if they try to reload the page in the browser they are forwarded to the login page (the 'someurl/view.xhtml?pid=5' still intact) and on succesful login go back to the view.xhtml page where I wan't the view to be constructed as if their session had never timedout.
However this does not happen because the 'pid' parameter is no longer set in the view. But since the 'pid' parameter is still visible in the url I feel like I should be able to get it into the view and load the protein with this id from the database.
These are the things I've tried:
#{protein.setProteinById(param.pid)}
and
#{protein.setProteinById(param['pid'])}
and
#{protein.setProteinById(request.getParameter('pid'))}
and
<c:set value="${request.getParameter('pid')}" var="pid" />
#{protein.setProteinById(pid)}
Is this possible to do? Then how?
I'm no expert, but wouldn't you set it in the managed bean?
As far as I know there are two methods for doing this.
One method is using in your facelet to push a view parameter back into a bean (I have a scenario where this doesn't work because of other things, so have no experience with it)
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
I have a prerender method, which is always called before a render
<f:metadata>
<f:event type="preRenderView" listener="#{MyController.prerenderMethod}" />
</f:metadata>
And inside the method, I look at the parameters:
public void prerender(ComponentSystemEvent event) {
value = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("key");
}

How to redirect to a page using Primefaces commadLink and bundle.properties file

I have a Primefaces commandLink which I have used it many times in my application. Now I want to store it's URL in a bundle.property file to make it maintainable. which xhtml attribute should I use to redirect it?
I already tried things like:
actionListener="#{bundle.Myurl}"
action="#{bundle.Myurl}"
target="#{bundle.Myurl}"
Myurl also contains this: sales/index.xhtml
but none of them run as I want!
You shouldn't use command links for page-to-page navigation in first place. Use a normal link.
If you have an internal URL / (implicit) navigation outcome:
<h:link value="link" outcome="#{bundle.Myurl}" />
Or if you have an external URL:
<h:outputLink value="#{bundle.Myurl}">link</h:outputLink>
Your attempts failed because the actionListener and action attributes are declared as MethodExpression attributes, meaning that any EL will be interpreted as a bean action method. The target attribute has an entirely different meaning, which is exactly the same as the generated HTML <a> element has.
See also:
When should I use h:outputLink instead of h:commandLink?

How to change the order of creation/restoring managed beans?

I have a complex problem with order of 'JSF bean life cycle actions'.
I have two beans with different scopes. The first, let's call it, managerBean is session scope bean. The second one, someBean has view scope (someBean really is many different beans). ManagerBean takes some action once per page loading and few others view scope beans are using the results of this action in their constructors.
Everything was working just fine until I've started getting forms IDs in xhtml files from java beans. Now action from managerBean is taken after someBean is created and I'm getting expected result only when the page is reloaded (on refresh, so someBean is using the first results of ManagerBean work).
This is how it looks like now:
<!-- mainTemplate is a main templete of the page which is rendered once
per page view (every other actions are taken via ajax). This is a place
of ManagerBean work after re rendering the page -->
<ui:composition template="/mainTemplate.xhtml">
<ui:define name="mainContent">
<h:form id="#{someBean.formID}">
some inputs
</h:form>
(...)
</ui:define>
</ui:composition>
So when form id was constant String everything worked like I want and now it doesn't. It looks like JSF must calculate ID first and take any other after this (including ManagerBean action).
My question is: Is there a way to change this situation?
If something isn't clear enought, please ask. I was trying to simplify the problem because it has many factors. Maybe all my thinking is wrong (the way I want to take some action per page and some actions after it).
Any help will be good!
The id (and binding) attribute of a JSF UI component is evaluated during view build time. The view build time is that moment when the XHTML source code is turned into a JSF UI component tree. All other attributes of a JSF UI component like value and all events like preRenderView are evaluated/executed after the view build time, usually during view render time (when the JSF UI component tree needs to produce HTML output). This is not something which you can change by just turning a setting or so. It's just the way how JSF works. You can't render something which isn't built yet. You can only change this by writing code the right way.
I can't think of any real world scenario why you need to make the ID attribute dynamic like this. If it were inside a <c:forEach>, or part of dynamic component generation, then okay, but this seems just to be a static form. So I would in first place recommend to forget it and just hardcode the ID in the view and rely on other variables (perhaps a hidden input field? depends all on concrete functional requirement which isn't mentioned anywhere in the question nor guessable based on the code posted so far).
If you really need to make it dynamic, then you need to split the formID property off from the view scoped bean and move it to a different and independent bean, perhaps an application scoped one.
See also:
JSTL in JSF2 Facelets... makes sense? - component's id attribute has same lifecycle as JSTL tags

Resources