Path to a file up in the hierarchy - jsf

Here is file structure of my JSF application.
User directory is secured & one needs to authenticate to see user/success.xhtml. user/success.xhtml has a button which is used to logout. That button submits form to following method.
public String logout(){
HttpSession session = (HttpSession)FacesContext.getCurrentInstance().getExternalContext().getSession(false);
session.invalidate();
return "index";
}
Last line of above method is there to redirect user to index.xhtml, as index.xhtml is not in the same directory as user/success.xhtml so I am getting following error.
Unable to find matching navigation case with from-view-id
'/user/success.xhtml' for action '#{AccContrl.logout()}' with outcome
'index'
How can I redirect to a file present up in the hierarchy?
I tried return "/../index"; but it didn't work.

The navigation outcome represents a view ID. If it does not start with /, then it is interpreted relative to the current path. If it starts with /, then it is interpreted relative to the web root.
So, just use /index.
return "/index";
Unrelated to the concrete problem, you should be redirecting here, not navigating. Not only because you should always perform a redirect when you intend to naviage away after POST, but also because the invalidated session is still present in the current request/response, but only not anymore in the next one.
return "/index?faces-redirect=true";
See also:
What is the difference between redirect and navigation/forward and when to use what?
How to navigate in JSF? How to make URL reflect current page (and not previous one)
How to invalidate session in JSF 2.0?

Related

display a success message on different portlet

I have form on a porlet, after submission of that form, page is redirecting to another portlet for that i am using actionResponse.sendRedirect("/abc/bcd/newWebPage")
and i am landing on to different page. One that page the same potlet is added with different screen, Now i want to display a success message on next page.
for that i am using portlet session and passing parameter to jsp.
PortletSession session = actionRequest.getPortletSession();
session.setAttribute("SUCCESSA", "Successfully",PortletSession.APPLICATION_SCOPE);
But its not working.
Any help how to achieve that?
When you say One that page the same potlet is added with different screen, I understand that you have another instance of the same portlet in different page. By the way, you haven't explained what is not working for you. I assume you are wondering how to read in the JSP page. It's pretty straight forward:
In Controller:
PortletUtils.setSessionAttribute(request, "SUCCESSA", "Successfully", PortletSession.APPLICATION_SCOPE);
In JSP:
pageContext.setAttribute("succcessa", PortletUtils.getSessionAttribute(renderRequest, "SUCCESSA", PortletSession.APPLICATION_SCOPE));
The PortletUtils does the same as setting the attribute using the PortletRequest object but its preferrable.
To remove the session attribute:
PortletUtils.setSessionAttribute(request, "SUCCESSA", null, PortletSession.APPLICATION_SCOPE);
The implementation of PortletUtils is that it removes the session attribute if value is null, if a session existed at all.

Dynamic page url using jsf

I need a page with URL that is dynamic. Let's suppose user profile page.
Example :
URL for user profile (salah) socail.com/salah and page must appear salah data
URL for user profile (wael) socail.com/wael and page must appear wael data
How can I do this using JSF framework .
You need to have a servlet with mapping appropriate for your needs, something like this:
#WebServlet("/")
Then when someone enters URL like yourpage.com/<anything here> then this servlet is gonna handle the request. To get a username from that url you need to do something like:
String username = request.getRequestURI().substring(1) - that is gonna get request info without the hostname and strip / from it.
Set the parameter (your info) so you can retrieve that in JSF:
request.setAttribute("userInfo", getSomeInfoByUsername(username));
Then you can forward the request to your JSF view file, like this:
request.getRequestDispatcher("faces/index.xhtml").forward(request,response);
Then in JSF file you can do something like this to get the info from request:
<h:outputText value="#{requestScope.userInfo}"/>
If I didn't miss anything those are all the pieces you need, getting username from URL can probably be retrieved in a better way, but nothing comes to my mind right now.
More about servlets here
If I understand you correctly,you want to dynamically redirect the control on the basis of request/session attributes:
You can take help of ExternalContext. For example:
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.redirect(context.getRequestContextPath() + "userProfile.jsf?user=" + user);
user is the attribute passed through backing bean.
Having said that I assume that you have already worked with JSF.

JSF web application -- opening a particular page based on url parameters

Our project uses a Web Application developed using JSF, primefaces, xhtml. Currently user can login and navigate through pages sequentially by clicking on 'action' links, like:-
index.xhtml --> login.xhtml --> classes.xhtml --> students.xhtml --> student_info.xhtml
i.e. first login --> shows the list of classes --> user selects a class --> shows the list of students in that class --> user selects a student --> shows the student info.
Each of the pages has its own 'backing bean' classes. They are instantiated as and when the user clicks through the pages.
Also, user can navigate back via certain links on each page-- say, from 'student_info' page, he/she can go back to the 'students' page.
Now requirement is: user can directly go to an inner page, say, student_info page by typing an 'url' with additional parameters, ?user=alice,?passwd=xyz, ?class=5, ?studentRollNo=15.
Also, the user should still be able to navigate back to other pages (i.e. once the page is opened, their should be no behavior difference whether the user navigated normally to student_info page or, whether he directly provided url with parameters).
My questions are:-
How to read url parameters in JSF?
Which page (or backing bean) should handle the parameters? Should it be done centrally, or, in each page (backing bean) ?
In case each page handles its relevant parameters only -- is there way to redirect remaining parameters to the next page ?
What are the best practices used in such implementations?
Note:
Actual web application is much more complex, tried to provide a simpler picture which pinpoints my problem.
new to JSF, Web App etc. Don't know if there are some JSF terminologies to describe above issues.
you can pass it by url request, and each BackingBean handle it
ex:
mypage.xhtml?myparam=test
and inject the HttpServletRequest in your BackingBean (if you are using CDI)
#Inject
HttpServletRequest request;
and get the param
#PostConstruct
public void init() {
String myparam = request.getParameter("myParam");
}
for redirect to other page you can use
public String redirect() {
return "otherPage.xhtml?faces-redirect=true&otherParam=test";
}

Jsf Template Showing Incorrect Url

I am using jsf2 and RichFaces. I want to track each page being browsed by the user.
For that I have created Servelet Filter which Intercepts the page being requested. In my project, I am using jsf template features where header and Footer are fixed. In the body part, I have defined menu.xhtml and an iframe tag. Response is targeted on to iframe whenever user clicks on any link on the menu.
My Problem is that, I am not getting the correct url of the page requested in the filter.
My Filter Snap
Below Shown is the Filter,looking For xhtml Page.
chain.doFilter(request, response);
HttpSession session = req.getSession(false);
if( null != session && (uri.contains(".xhtml") || null != session.getAttribute("userid"))){
if(null != session.getAttribute("userid")){
String userid = session.getAttribute("userid").toString();
//for saving usage details
if(uri.contains(".xhtml")){
System.out.println(".......Requeted Page.........."+req.getRequestURL().toString());
saveUserUsage(req);
}
}
}
url getting in the filter is userdeskop.xhtml even though different links in the menu are selected.
Reason for the same url independent from the clicked menu might be the JSF Lifecycle:
it decides on server side on which page to deliver.
From that side, independent from what you click on e.g. a JSF Mojarra Implementation, the requested page might always be the same - just the parameters differ ... and the server does a redirect to the desired page (which is just too late for your filter to be recognized ;-) ).
Update: I would try to get a phase listener being executed before or after RENDER RESPONSE phase, because there the navigation goal should be resolved. Within the listener something like (untested example code)
public void afterPhase(PhaseEvent event)
{
FacesContext context = event.getFacesContext();
String viewId = context.getViewRoot().getViewId();
....
}
might help you resolve the final url.
If you only want to resolve the urls for the main menu (I guess, that links are static and no managed bean method needs to be invoked), you can alternatively use h:outputLink, which resolves to fixed urls ( see When should I use h:outputLink instead of h:commandLink? for details) - this will work with your already existing listener.
Hope it helps...

JSF: Bookmarkability with ViewScoped

I am trying to make my app "Bookmarkable", and i am using view parameters to achieve it.
And i think i still do not get the right way to do it right in JSF, even after reading this, and many others.
My problem is that the get parameters get lost after any non-ajax postback, i mean, the parameter value is still set in the bean and the app works correctly, but it gets removed from the URL making the URL invalid.
For instance, having an URL like http://company.com/users?id=4, as soon as that page executes a non-ajax postback (for uploading data, for instance) the URL becomes just http://company.com/users. The app continues to work correctly, but the link is not any more "Bookmarkable".
Is there any way to prevent the non-ajax postbacks removing the viewParams from the URL?
My use case is to be able to bookmark a page to EDIT an object, and there i need to be able to upload data (if not i would not use non-ajax postbacks). I know i would not need any postback if i would want to bookmark the page to only VIEW the data of the object, but that is not my case.
I could also do a redirect to the same page with the same params, and let the app to recreate the view scoped bean, but then i really do not see any benefit over request scoped beans...
Any suggestion is very appreciated.
This behaviour is "by design". The <h:form> generates a HTML <form> element with an action URL without any view parameters. The synchronous POST request just submits to exactly that URL which thus get reflected as-is in browser's address bar. If you intend to keep the view parameters in the URL, while using ajax is not an option, then you basically need to create a custom ViewHandler which has the getActionURL() overridden to include the view parameters. This method is used by <h:form> to generate the action URL.
public String getActionURL(FacesContext context, String viewId) {
String originalActionURL = super.getActionURL(context, viewId);
String newActionURL = includeViewParamsIfNecessary(context, originalActionURL);
return newActionURL;
}
Or, as you're based on the comments already using OmniFaces, you could also use its <o:form> component which basically extends the <h:form> with the includeViewParams attribute which works much like the same as in <h:link> and <h:button>.
<o:form includeViewParams="true">
...
</o:form>
This way all <f:viewParam> values will end up in the form action URL.
See also:
Handling view parameters in JSF after post

Resources