Get JSF 2 url to change after first, not second click - url

JSF URLs don't seem to change after the first click, only after the 2nd. E.g. when navigating from home.jsf to auction.jsf, the page being displayed is already auction.jsf but the URL in the browser address bar stays at home.jsf, until I click on the Auction link the second time. Why is this happening? Is there a way to disable it, and get the url to display correctly?

You seem to be navigating by POST instead of by GET. You should not perform page-to-page navigation by POST in first place. Replace <h:commandLink> by <h:link>.
So, do not navigate by
<h:form>
<h:commandLink value="Auction" action="auction" />
</h:form>
but by
<h:link value="Auction" outcome="auction" />
A JSF POST form basically submits to the current URL and any navigation is by default performed by a server-side forward using RequestDispatcher#forward() (if you are well familiar with the basic Servlet API, you know what this means). You could work around with performing a redirect instead
<h:form>
<h:commandLink value="Auction" action="auction?faces-redirect=true" />
</h:form>
but, as said, this is a work around not a solution.
See also:
When should I use h:outputLink instead of h:commandLink?

You need to add faces-redirect=true to your URL. Check out this short tutorial from Mkyong.com.

Related

CommandLink action redirect to external url not working

I am using jsf 2. I have a link in a facelet file that points to a external url. My current view is /app1/home.xhtml with a h:commandLink that has an action like so
<h:commandLink value="#{link}" action="#{action.redirect}" target="_blank"/>
the url that action.redirect redirects to is /app2/info.do. However it appears that JSF tries to change the extension of the url to .xhtml. and then fails with the error message.
com.sun.faces.context.FacesFileNotFoundException: /app2/info.xhtml Not Found in ExternalContext as a Resource
how do i get this to correctly redirect ?
Don't use the <h:commandLink> here, it's the wrong tag for the purpose. It is designed to submit a JSF POST form and navigate to a JSF view, both which you obviously don't want to let take place in this particular use case.
Just use the <h:outputLink> or even plain HTML <a>. So,
<h:outputLink value="#{action.redirect}" target="_blank">#{link}</h:outputLink>
or
#{link}
Note that you don't need the <h:form> in both approaches.

Simple jsf2.0 application : javax.faces.application.ViewExpiredException View could not be restored

In a simple jsf2.0 application,I am getting this exception :javax.faces.application.ViewExpiredException View could not be restored.
In console I am getting following error:
org.portletfaces.bridge.BridgeException: Must first call setPortletContext(PortletContext)
When I executed my application without useing Primefaces jar it worked properly. But after addind Primefaces jar I started getting this exception.
I am using Tomcat 7.2.
EDIT: There are only 3 pages in the application and no backing bean.. A link on first page is invoking second page. But when I click on the link I am getting this error and the second page is not displayed.
Cant understand the cause of the problem. Please help.
There are only 3 pages in the application and no backing bean.. A link on first page is invoking second page. But when I click on the link I am getting this error and the second page is not displayed.
That can happen if you're navigating by UICommand links/buttons. You should not navigate by POST links/buttons at all, but just by GET links/buttons.
Replace all those UICommand links/buttons which are incorrectly been used for page-to-page navigation by normal UIOutcomeTarget links/buttons. In other words, replace <h:commandButton> by <h:button>, <h:commandLink> and <p:commandLink> by <h:link> and <p:commandButton> by <p:button>.
I.e. do not use
<h:form>
<p:commandButton value="Go to next page" action="nextpage" />
</h:form>
but instead use
<p:button value="Go to next page" outcome="nextpage" />
See also:
When should I use h:outputLink instead of h:commandLink?

How to detect whether user have reached a page by JSF navigation rule redirect or by typing the URL?

Is there any way in JSF which can be used to find out whether an user reached a page by the Navigation rule of the JSF or user has typed the URL directly to reach that page?
Actully I want to prevent user to go to a page directly by typing the URL for that directly in the Browser, rather I want to restrict the user to use the application navigation bar to go to an page.
There is a way: check the presence of the referer header (yes, with the misspelling).
if (externalContext.getRequestHeader("referer") == null) {
// User has most likely accessed the page by directly typing the URL.
}
or
<h:panelGroup rendered="#{empty header['referer']}">
<!-- User has most likely accessed the page by directly typing the URL. -->
</h:panelGroup>
This will however fail for users who have neatly used the link in your webpage, but are using some overzealous proxy/firewall/security software which hides the referer header altogether.
You might want to consider to make the page never directly available to users by placing it in /WEB-INF folder and using it as a conditional include which is executed by a POST request (if necessary with ajax). E.g.
<h:form>
<h:commandLink action="#{bean.showPage}" />
</h:form>
<h:panelGroup rendered="#{bean.showPage}">
<ui:include src="/WEB-INF/includes/foo.xhtml" />
</h:panelGroup>

How to create a link or button which calls an action and doesn't preserve cid?

Here is a simple usecase which I don't manage to realise : I want to create a link or button which calls a server method (action) and will redirect to a page without preserving the cid parameter.
I'm using JSF2, JBoss 7 and Seam 3.
Here are two methods I tried without success.
First one, the h:commandLink
<h:commandLink action="pages/home.xhtml"
actionListener="#{identity.logout()}"
value="#{bundles.layout.logout}" />
Here, identity.logout() is called, but then, the browser is redirected to pages/home.xhtml?cid=1, so if I login again, I will have an
org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.enterprise.context.ConversationScoped
error.
Second one, the h:link
<h:link outcome="/pages/home.xhtml" value="#{bundles.layout.logout}">
<f:ajax event="click" listener="#{identity.logout()}" />
</h:link>
Here, I don't have any cid in the generated hyperlink, but the method identity.logout() is not called...
Does someone have an idea ?
Using h:commandLink and calling conversation.end() from identity.logout() should work. You didn't include the code for identity.logout(), but I suspect you're not ending the conversation. By ending the conversation, you change it from long-running to transient, at which point it should not be propagated.

synchronisation of pages in address bar in a web application using jsf2

I'm working in a jsf2 application and I have a problem with the page name displayed in the address bar. When I navigate to an other page I have in address bar the name of the previous page.
Thanks.
That's because you're using POST instead of GET for page-to-page navigation and JSF defaults to submitting to the very same view with you're using <h:form>. Using POST for page-to-page navigation is in any case a very poor approach. It's not only not user friendly (it's not bookmarkable and confusing), but it's also not SEO friendly (searchbots don't follow <form> actions).
To solve this problem, you must stop using <h:commandLink> for page-to-page navigation. Use <h:link> instead.
<h:link value="Go to next page" outcome="nextpage" />
This will just render a
Go to next page
Which is perfectly bookmarkable, user friendly and SEO friendly.
When you're navigating to a different page as result of a real POST form submit, I'd also replace that by returning null or void and just render the result/messages conditionally in the very same view. Or if the result is supposed to be bookmarkable (e.g. search results), you should use normal links or plain <form> instead of <h:form> and use <f:viewParam> in target view.
See also:
When should I use h:outputLink instead of h:commandLink?
This is happerning because, in JSF, when you are navigating to a new page the server is performing a forward to the new page. The browser is unaware of the forwarding and is displaying the old url. To make the server perform a redirect instead of forwarding, you have to either:
If you are using navigation rules, add a <redirect/> to each rule:
<navigation-rule>
<from-view-id>/pages/from.xhtml</from-view-id>
<navigation-case>
<from-outcome>to</from-outcome>
<to-view-id>/pages/to.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
If you are returning an outcome from a bean method, add a ?faces-redirect=true to the outcome:
public String navigate() {
return "/pages/to?faces-redirect=true";
}

Resources