Previous Page URL JSF - java

I'm working with a JSF application and I'm seeing the URL that appears in the browser's navigation bar is always for the page I just left, rather than the page I'm on.

It is because you are forwarded(not redirected) to another page from server, To redirect you need to set the following param with your return
?faces-redirect=true

That will happen if you're using POST for navigation by e.g. commandlinks/commandbuttons. If it's pure page-to-page navigation and you actually don't need to submit anything to the server, then you've a bigger problem. You will indeed get exactly this nasty "side effect" and your links will not be bookmarkable nor searchbot-crawlable. PRG (Post-Redirect-Get), as suggested by other answers, will indeed solve the bookmarkability ("one URL behind") problem, but it surely won't solve the inability of searchbots to crawl/index the pages.
Just don't use POST for plain page-to-page navigation in first place. Use GET for that. Use <h:link> instead of <h:commandLink> and so on. In code, replace all
<h:form>
<h:commandLink value="Next page" action="nextpage" />
</h:form>
by
<h:link value="Next page" outcome="nextpage" />
See also:
When should I use h:outputLink instead of h:commandLink?
What is the difference between redirect and navigation/forward and when to use what?

By default, JSF performs POST operations directed to the original page's URL. If you use a <navigation-rule>, you can specify <redirect/> to let the browser perform an additional request, so the target page's URL will appear in the navigation bar.

Related

How to redirect user to different pages based on the submit button in Struts 2

First, please note I know the following code is not in JavaScript or jQuery but I just added them as tags of this question in hope of finding a solution for it using Javascript or jQuery.
I have a form with three submit buttons. The problem is that, when I submit the form with either of the buttons the result page will be sent to the same address. I need it to be in a different address.
Purpose:
The code is supposed to show a list of items for a specific category in a page called view. User selects few items and submit the form. Server needs to show the details of the selected items in a page called update (separate address with view page). Then user is able to edit the details of items and submit the form to update the details of those items.
Requirement:
lets say address is
myexample.com/Product/view //shows view page
after clicking on edit, it should redirect to following address.
myexample.com/Product/update //shows update page ( show details of selected products)
Potential Solution:
Based on Roman C's answer, after receiving the request, I pass the products list to the other action to show update page, but it shows it as following on the address; therefore, update page does not recognize products parameter as a list.
...products=[1%2C+2]&id=1
Java:
List <Integer> products = new ArrayList();
Struts redirect:
<result name="updateProducts" type="redirectAction">
<param name="actionName">update</param>
<param name="namespace">/products/Update</param>
<param name="products">${products}</param>
<param name="id">${id}</param>
</result>
Even if I manually send the following request, the action class does not recognize products parameter as a list. It shows it's size is Zero.
...products=[1,2]&id=1
You should add a redirectAction result to the action config of the action that processes a submit request. In your case it has an edit name, that is confusing, should name like save or update because when you name it edit many programmers think like you are making a request to populate some textfields. But it's not true, your edit action doesn't populate, rather than submits to the server. After submit you should follow the Post-Redirect-Get pattern and return a redirectAction or redirect result to the other action or URL not nessesary to view or edit actions if you don't want to stay on the page after redirecting. Remove the edit action config as it has covered by the wildcard mapping. Add the save button
<s:submit id="saveBtn" action="save" value="Save"/>
add and return redirect action result from the save action
<action name="save" method="save" class="myexample.Product">
<result type="redirectAction" name="list" />
</action>
How to redirect user to different pages based on the submit button of the form that is pressed:
URL redirection is a World Wide Web technique for making a web page available under more than one URL address. When a web browser attempts to open a URL that already has been redirected, a page with a different URL is opened.
For example, www.example.com is redirected to example.iana.org.
Similarly, Domain redirection or domain forwarding is when all pages in a URL domain are redirected to a different domain, as when wikipedia.com and wikipedia.net are automatically redirected to wikipedia.org.
URL redirection can be used for URL shortening, to prevent broken links when web pages are moved, to allow multiple domain names belonging to the same owner to refer to a single web site, to guide navigation into and out of a website, for privacy protection, and for less innocuous purposes such as phishing attacks.
<form action="http://example.org/ jmail1.java">
<input type="submit" value="Go To jmail1.java">
</form>
<form action="http://example.org/jmail2.java">
<input type="submit" value="Go To jmail2.java">
</form>
Techniques:
Several different kinds of response to the browser will result in a redirection.
These vary in whether they affect HTTP headers or HTML content. The techniques used typically depend on the role of the person implementing it and their access to different parts of the system.
For example, a web author with no control over the headers might use a Refresh meta tag whereas a web server administrator redirecting all pages on a site is more likely to use server configuration.
<action name="foo">
<result type="redirectAction">
<param name="actionName">bar</param>
<param name="namespace">/</param>
</result>
</action>
Although Info path gives you the ability to create a custom message after submission, lots of users have requested more than that. They haven’t been happy with the way the form just leaves you sitting there in the List, it can be confusing. So we have a way in which you can make an InfoPath form function like a traditional web form wherein you fill out the form and upon clicking the ‘Submit’ button, the user is taken to a Thank You page
Resolution:
Create a Thank You page and save it somewhere on your site. We recommend using any editor, like Notepad or SharePoint Designer to create an html page with a message of your choosing such as “Thank You for your submission”
Click on that Thank You page and record the URL I.E., it will look something like this: http://mydomain.com/sites/YourSite/YourDocLibrary/ThankYou.html
Now you need to figure out the URL to your InfoPath form. Either click on it and record the URL or if you have attached the InfoPath form to a SharePoint List, then you will need to alter the URL like this: http://mydomain.com/sites/YourSite/YourList/NewForm.aspx, as you can see we just added the NewForm.aspx to the end of it.
Take the URL you recorded in step 3 and add the following:? Source=http://mydomain.com/sites/YourSite/YourDocLibrary/ThankYou.html, So the URL should look like this: http://mydomain.com/sites/YourSite/YourList/NewForm.aspx?Source=http://mydomain.com/sites/YourSite/YourDocLibrary/ThankYou.html << this is the link you will send to your users in order to fill out your form. When your users click on this new link, it will tell SharePoint to automatically redirect them to your Thank You page after they submit.
On that Thank you page you can add a link to go to another page or you can get real fancy and add a Meta refresh tag to automatically take redirect your users, for example, to the home page of your site. How do you do that? Simple. Add this line: <meta http-equiv="refresh" content="2;url=http://mydomain.com/sites/yourSite/"> in between the tags of your HTML page. Just to explain a little more about that line, the number 2 in this case represents 2 seconds. So you can modify that to keep the user on that page longer or shorter by replacing that number with a different one. The url would be the url of your home page or any other site you want to redirect the user to.
<table><tr>
<td><s:submit name="update" value="Update" action="update" ></s:submit></td>
<td><s:submit name="delete" value="Delete" action="delete" ></s:submit></td>
</tr></table>
<action name="update"
class="net.viralpatel.struts2.action.MemberCrudOpertaions"
method="updateUser">
<result>members.jsp</result>
</action>
<action name="delete"
class="net.viralpatel.struts2.action.MemberCrudOpertaions"
method="deleteUser">
<result>members.jsp</result>
</action>`
Manual redirect:
The simplest technique is to ask the visitor to follow a link to the new page, usually using an HTML anchor like:
Please follow this link.
This method is often used as a fall-back — if the browser does not support the automatic redirect, the visitor can still reach the target document by following the link.
Default redirect:
The Default redirect technique is to ask the visitor to follow a link to the new page, usually using an HTML with JSP like:
<html>
<%
String redirectURL = "http://stackoverflow.com/";
response.sendRedirect(redirectURL);
%>
</html>
http://struts.apache.org/release/2.2.x/docs/redirect-action-result.html
http://struts.apache.org/development/2.x/docs/multiple-submit-buttons.html
http://struts.apache.org/development/2.x/docs/submit.html
http://struts.apache.org/release/2.2.x/docs/interceptors.html
related source : http://en.wikipedia.org/

RichFaces: TabPanel and param

Currently, i am dealing with rich:tabPanel in my web application based on JSF 2.0.
I encounter a very strange problem, which is related to my richface component.
Basically, i print some same stuff on each panel (here, it is a schedule table of a show, tab contains the day and content of tab contains the differents hours ).
Consequently, i have something like that:
<rich:tabPanel>
<c:forEach items="#{show}" var="hour" ...>
<rich:tab>
<a4j:commandLink ...>
<a4j:param value="hour.something" assignTo="#{bean.method}" />
</a4j:commandLink>
</ ..... >
When i click on the first commandlink, when my webpage is displayed, it's ok. But when i choose an other tab, and i click on the commandlink, the "bean.method" is not call. I need to click a second time to make the call of the function.
Finally, when i put the tabPanel as "switchtype=server", it works very well (without clicking 2 times).
But that's not the purpose, i want to use the client mode.
I see that on JIRA of richfaces v3, this problem has been solved JIRA JBoss. But there is no more information (except a comment but it's not working).
If anyone can help, it would be great.
Regards,
The problem is you are using nested forms(form within form). This is not recommended in JSF. Even in HTML it is invalid. Remove one form and it will work.
Read this post too.

h:link in JSF gets called automatically

I am creating a user authentification in JSF2, and my header displayed on every page contains this:
<c:if test="#{user.loggedIn}">
<li><h:link value="Log out" outcome="#{user.logout}"/></li>
</c:if>
User refers to the userBean, and logout() simply invalidates the session, and issues a redirect to the login page. So when the user logs in, user.loggedIn becomes true, and logout link gets displayed, but it somehow immediately gets called, and the user is immediately logged out.
Does anyone have an idea why is this happening? I thought of using h:commandLink, but it requires a form, and I'm trying to avoid it.
Edit:
I copied the wrong code... just my luck after spending an hour figuring out why the user cannot login. You can look at the previous revision to see miscopied code.
That can happen when the JSF tags are not recognized and parsed as such and it effectively get rendered as plain text wherein all EL expressions are evaluated as value expressions. It would in your case basically print the returned value of #{user.logout()}. But while EL does that, the method's logic is of course invoked.
If you remove the action attribute and open the page in browser and do a View Source, then you'll see an unparsed <h:commandLink> tag instead of the generated HTML <a> element.
Make sure that you have the h: XML namespace definied on the right URI in the root tag of the view file.
xmlns:h="http://java.sun.com/jsf/html"
Update: the <h:link> isn't intented to invoke bean actions. It's intented as a pure GET link. The outcome is per specification evaluated as a value expression, not as a method expression. The outcome must represent a view ID where the link has to navigate to. When the EL evaluates your method as a value expression, it's of course immediately invoked. Just keep using <h:commandLink> in combination with a redirect. Additional advantage is that this isn't bookmarkable nor searchbot-crawlable.
This is the example from jsfToolbox:
<h:commandLink id="link1"
value="#{bundle.checkoutLabel}"
action="#{shoppingCartBean.checkout}" />
Get rid of your parens at the end of logout.

Richfaces: Link-like text with ContextMenu

I want to render using Richfaces a context menu on left click on a link-appearing text (blue text, and underline and cursor onmouseover). So, imagine a link which when clicked shows a context menu. Note that I don't care if the text is indeed a link, I just want it to appear as a link. So, even normal text would be fine, I would make it appear as a link using CSS.
I have the following conditions:
The context menu must appear on client side, without making a request.
The context menu must appear using a rich:componentControl (these "links") are inside a datatable, so the same rich:contextMenu must be re-used.
I still have not found a satisfactory solution, as each approach I have tried has caused a problem for me:
If I use h:outputText (that would be ideal), I cannot attach on it a rich:componentControl (I guess because it cannot fire an onclick event).
If I use a4j:commandLink, although I can attach a rich:componentControl, it makes a server request. I tried to add onclick="return false;" to prevent the request, but Richfaces adds the JS generated by the rich:componentControl after whatever is inside the onclick, which causes this code not to be reached at all, and of course the context menu not to appear at all.
Is there any way to do this? Please remember, no request!
You may try
<rich:componentControl disableDefault="true" ...>
According to documentation with this param componentControl should add return false; itself.
But be aware of corresponding bug: RF-5607
In case documentation lies you may use html anchors. This answer shows how to create a link with componentControl and without page refresh:
<h:outputLink value="#" id="link" onclick="return false;">
<h:outputText value="Link text"/>
<rich:componentControl attachTo="link" for="panel" operation="show" event="onclick"/>
</h:outputLink>
The onclick="return false;" prevents the anchor from scrolling the page to the clicked link.

Calling JSF ManageBean after PageLoad using f:event postAddToView

I am writing an app using JSF 2.0.
For one of the page, there is a section of the page that takes a long time to display.
To improve the user experience, I am thinking to load the page first and then automatically do an Ajax call back to the JSF manage bean object once the page is loaded successfully after 1st load.
I am thinking to use f:event with type postAddView.
<h:outputText id="dummyId">
<f:event type="postAddToView" listener="#{mngBean.doSomething}" />
</h:outputText>
However it seems like f:event postAddToView is still being processed before the page is displayed for the first time.
The other options that I have explore is to create a hidden button and get javascript to trigger it. It works however I am just wondering if there is a nice JSF component/event that can do this instead of using java script.
Thanks for your help.
<h:commandButton id="dmyButton"
value="#{mngBean.getSomething}"
actionListener="#{mngBean.doSomething}"
style="display: none"
type="submit">
Java Script
<script language="JavaScript">
$(document).ready(function() {
if (document.getElementById('form:dmyButton').value == 'true') {
document.getElementById('form:dmyButton').click();
}
});
</script>
Thanks for all your help in advance
I think the PreRenderViewEvent is what you want.
http://javaserverfaces.java.net/nonav/docs/2.0/javadocs/javax/faces/event/PreRenderViewEvent.html
Though the docs don't show it, the preRenderViewEvent does work with f:event. I'll fix the docs presently.
PostAddToViewEvent is processed "During Restore View Phase, after a
component has been added to a view." (according to Java Server Faces 2.0 - The Complete Reference) which means it is really early in the lifecycle (Restore View is the first lifecycle phase).
I don't think that any PhaseListener will help you in this case, since they all run on the server side, not on the client side.
However, <f:ajax> can be applied to <h:body>, with event="load". I tried it, but it didn't really work, <f:ajax> wrapping <h:body> nothing happened, the other way around I got Unable to attach <f:ajax> to non-ClientBehaviorHolder parent error.

Categories