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";
}
Related
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.
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.
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...
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
I have the following scenario in my project based on JSF and RF3.3
1.Each of the operation in the application is traced. That is if user opens a certain page the information about the page is stored against the name of the user.
Now the pages can be createSomething or ModifySomething...
This both pages are linked to the same backing bean since they belong to same module.
So when I trace information of user based on constructor call I cannot store the information as to whether the bean was loaded for createSomething page or ModifySomething page.
I want to get the name of the page or something unique using which I can identify whether the bean is loaded for CreateSomething or ModifySomething.
I want to know how can I trace or log information for only a page visit.i.e. user clicked on the page but didn't performed any action.
For any action performed on the page I can easily keep a record of it..
I cannot use Javascript...
Kindly guide me.
You can get the JSF view ID by UIViewRoot#getViewId() as follows:
String viewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();
// ...
It will return the view identifier which is the unique path of the view root, such as /create.xhtml or /edit.xhtml.
An alternative is to let the page invoke a page-specific <f:event type="preRenderView"> listener method. For example, only in the create page:
<f:event type="preRenderView" listener="#{bean.prepareCreate}" />
with
public void prepareCreate() {
if (!FacesContext.getCurrentInstance().isPostback()) {
entity = new Entity();
}
}