Dynamic page url using jsf - 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.

Related

Different kind of redirection in a portlet

I would like to know the different kind of redirections in the portets and how to realize them. How to go from one view (jsp file) to another in the same portlet, how to go from one page to another from a portlet. It is for the purpose of making a form so I would like to do this in a processAction.
Your answer is not clear.
However, in Liferay, you can route your application using urls.
For example, you can create a portlet action url on your own.
You can try something like this:
HttpServletRequest request = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(actionRequest));
PortletURL oPortletURL = PortletURLFactoryUtil.create(request, <portletName> , <plid>, <portletPhase>);
oPortletURL.setParameter("myParameter1", "parameter1");
String portletURL = oPortletURL.toString();
Where:
<portletName> is the javax.portlet.name of your portlet
<plid> is the ID of a page where is located an instance of your <portletName> portlet (try to check Layout and LayoutFriendlyUrl tables)
<portletPhase> is the phase you need, for example PortletRequest.ACTION_PHASE
Finally, you can use setParameter() method to pass parameters in query string.
On the jsp for a single portlet: If you use Liferay's MVCPortlet, you can just add the mvcPath parameter with the name of the JSP, to make sure your portlet renders with this JSP. Nothing else.
Pages have a URL. If you want to redirect to another page, you'll have to configure the page's URL somewhere. However, that's rarely done unless you're implementing a Navigation portlet. Your question sounds more like you have a multi-page portlet.

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.

Path to a file up in the hierarchy

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?

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: 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