Retrieve public render parameter from OrignalParameterMap in renderRequest - portal

I have passed a render parameter from one portlet to another using user friendly url navigation.
response.setRenderParameter("params", renderParams);
response.sendRedirect(response.encodeURL("/wps/myportal/Home/abcPortlet"), "params");
Here Home and abcPortlet are user friendly page names for specific pages.
While debugging I found that OriginalParameterMap contains the render parameter in its URL.
Can someone tell me how to retrieve it? As usual getter methods are not able to retrieve that value.

You cannot pass render parameters from one portlet to another. It has to be Pubic Render Parameter (PRP). The approach of setting PRP is same as that of render parameter, but both portlets should agree that, they support that PRP. For that you need to register the supported PRPs in portlet.xml file of both the portlets. Please refer to this link for more info.This is what the specification insist. Imagine a scenario where in we have multiple portlets from various vendors on a portal page. It is a security concern if one portlet could retrieve the parameters from the URL even if it is not targeted to that portlet.
Another approach (which is not recommended) is to type case the RenderRequest to HttpServletRequest and get the parameter from request. It is not mentioned in the specification that PortletRequest should be a HttpServletRequest. So it is better not to do that. Future implementation of Portal can change this.
Third approach is to use the URL Generation APIs and construct the URL which has the parameters targeting the portlet. You can refer to the below link which has some helper classes. This will simplify your job. Advanced URL Generation Helper Classes
The best way is to use PRP. Both the source portlet and target portlet are loosely coupled.

Related

The page change but not the URL on clicking <p:commandButton> [duplicate]

I am currently learning JSF and was rather amazed and puzzled when I realized that whenever we use <h:form>, the standard behavior of JSF is to always show me the URL of the previous page in the browser, as opposed to the URL of the current page.
I understand that this has to do with the way JSF always posts a form to the same page and then just renders whatever page the controller gives it back to the browser which doesn't know the page location has changed.
It seems like JSF has been around for long enough that there must be a clean, solid way to deal with this. If so, would you mind sharing?
I have found various workarounds, but sadly nothing that seems like a real solid solution.
Simply accept that the URL is misleading.
Append "?faces-redirect=true" to the return value of every bean's action and then
figure out how to replace #RequestScoped with something else (Flash Scopes, CDI conversation, #SessionScoped, ...).
accept to have two HTTP round trips for every user action.
Use some method (e.g. 3rd party library or custom code) to hide the page name in the URL, always using the same generic URL for every page.
If "?faces-redirect=true" is as good as it gets, is there a way do configure an entire application to treat all requests this way?
Indeed, JSF as being a form based application targeted MVC framework submits the POST form to the very same URL as where the page with the <h:form> is been requested form. You can confirm it by looking at the <form action> URL of the generated HTML output. This is in web development terms characterized as postback. A navigation on a postback does by default not cause a new request to the new URL, but instead loads the target page as content of the response. This is indeed confusing when you merely want page-to-page navigation.
Generally, the right approach as to navigation/redirection depends on the business requirements and the idempotence (read: "bookmarkability") of the request (note: for concrete code examples, see the "See also" links below).
If the request is idempotent, just use a GET form/link instead of POST form (i.e. use <a>, <form>, <h:link> or <h:button> instead of <h:form> and <h:commandXxx>).
For example, page-to-page navigation, Google-like search form, etc.
If the request is non-idempotent, just show results conditionally in the same view (i.e. return null or void from action method and make use of e.g. <h:message(s)> and/or rendered).
For example, in-page data entry/edit, multi-step wizard, modal dialog, confirmation form, etc.
If the request is non-idempotent, but the target page is idempotent, just send a redirect after POST (i.e. return outcome with ?faces-redirect=true from action method, or manually invoke ExternalContext#redirect(), or put <redirect/> in legacy XML navigation case).
For example, showing list of all data after successful editing, redirect after login, etc.
Note that pure page-to-page navigation is usually idempotent and this is where many JSF starters fail by abusing command links/buttons for that and then complain afterwards that URLs don't change. Also note that navigation cases are very rarely used in real world applications which are developed with respect to SEO/UX and this is where many JSF tutorials fail by letting the readers believe otherwise.
Also note that using POST is absolutely not "more secure" than GET because the request parameters aren't immediately visible in URL. They are still visible in HTTP request body and still manipulatable. So there's absolutely no reason to prefer POST for idempotent requests for the sake of "security". The real security is in using HTTPS instead of HTTP and checking in business service methods if currently logged-in user is allowed to query entity X, or to manipulate entity X, etc. A decent security framework offers annotations for this.
See also:
What is the difference between redirect and navigation/forward and when to use what?
JSF implicit vs. explicit navigation
What URL to use to link / navigate to other JSF pages
Bookmarkability via View Parameters feature
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
When should I use h:outputLink instead of h:commandLink?
Creating master-detail pages for entities, how to link them and which bean scope to choose
Retaining GET request query string parameters on JSF form submit
Pass an object between #ViewScoped beans without using GET params

Liferay static url for dynamic data

I want to serve some data from an static url in Liferay. For example, say to serve a json containing the logged user from "http://server.com/whatever/user" so all the portlets in the proyect can read it. Right now I can do it with a portlet, but then I have to set the url with the configuration panel and I don't like that.
I've seen that I can put jsp files with the static content, but don't know how to access the information of session, users, etc.
Friendly urls seem to accomplish something similar but seem overly complicated and focused in getting a short easy url, something I don't care.
So, how can I get some internal data in an static url (I don't mind if it's friendly, long or short, but always the same) so every element of a Liferay proyect can read it?
FOURTH EDIT: Another way to put it...
In my eclipse I have this tree:
/whatever-war/docroot/html/fancy-porlet/list.jsp
How do I access that jsp in a browser without having to go the Liferay panel and putting the portlet in the menus of the web?
FIFTH EDIT: I haven't had the time to research any more, but I have this in my notes...
https://server/language/c/portal/layout?p_l_id=plid
This goes straight to the portlet, sometimes. plid comes from
PortalUtil.getPlidFromPortletId(themeDisplay.getScopeGroupId(), name_of_portlet_and_war)
It's no solution for me because, it doesn't always work. Sometimes you get a numeric identifier, sometimes you get a zero. I'd bet on the name of portlet and war being incorrect so it doesn't find the portlet, but then, how do you find the new name of the portlet? Sadly, I discarded the code where the name came from, but is coming from Liferay.
SIXTH EDIT: What I want to do is to be able to call a fixed url, with some data internal to Liferay, and get information based on that data back.
There are several aspects here:
Every portlet already has access to the user through a request attribute called ThemeDisplay:
ThemeDisplay themeDisplay = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY);
Check ThemeDisplay's interface for the various options that you have in order to get the current user's id or object.
You've asked about JSON delivery - this will need to go through Liferay and not (directly) through a JSP in your individual web application. The reason is that any request processed by Liferay will contain the user's information, but as any proper webapp, it's completely separate from any request directed at another webapp: Unless included by Liferay, your JSP will have a different session that has nothing to do with Liferay's session. (I hope this explanation makes sense)
If you write a servletFilter hook, you might not yet have the portal context initialized (Liferay 6.x has been a while for me, pardon for being vague here). If you're on the portlet side, you might have to do more than you expected.
One option that you have is to embed a portlet on every page, automatically (e.g. when it's deployed, it's available). You can configure a portlet to be automatically included on every page, it's done for the chat portlet, for example. That portlet does not need to have any UI, it just needs to expose its resourceURL, so that you can use it from everywhere.
However, I somehow doubt that you use it, given that every portlet has the information already at hand.
But I might also just not understand all of your requirements...

getViewId(), getServletPath() and getRequestURI() all returns previous URL, how to get current URL? [duplicate]

I am currently learning JSF and was rather amazed and puzzled when I realized that whenever we use <h:form>, the standard behavior of JSF is to always show me the URL of the previous page in the browser, as opposed to the URL of the current page.
I understand that this has to do with the way JSF always posts a form to the same page and then just renders whatever page the controller gives it back to the browser which doesn't know the page location has changed.
It seems like JSF has been around for long enough that there must be a clean, solid way to deal with this. If so, would you mind sharing?
I have found various workarounds, but sadly nothing that seems like a real solid solution.
Simply accept that the URL is misleading.
Append "?faces-redirect=true" to the return value of every bean's action and then
figure out how to replace #RequestScoped with something else (Flash Scopes, CDI conversation, #SessionScoped, ...).
accept to have two HTTP round trips for every user action.
Use some method (e.g. 3rd party library or custom code) to hide the page name in the URL, always using the same generic URL for every page.
If "?faces-redirect=true" is as good as it gets, is there a way do configure an entire application to treat all requests this way?
Indeed, JSF as being a form based application targeted MVC framework submits the POST form to the very same URL as where the page with the <h:form> is been requested form. You can confirm it by looking at the <form action> URL of the generated HTML output. This is in web development terms characterized as postback. A navigation on a postback does by default not cause a new request to the new URL, but instead loads the target page as content of the response. This is indeed confusing when you merely want page-to-page navigation.
Generally, the right approach as to navigation/redirection depends on the business requirements and the idempotence (read: "bookmarkability") of the request (note: for concrete code examples, see the "See also" links below).
If the request is idempotent, just use a GET form/link instead of POST form (i.e. use <a>, <form>, <h:link> or <h:button> instead of <h:form> and <h:commandXxx>).
For example, page-to-page navigation, Google-like search form, etc.
If the request is non-idempotent, just show results conditionally in the same view (i.e. return null or void from action method and make use of e.g. <h:message(s)> and/or rendered).
For example, in-page data entry/edit, multi-step wizard, modal dialog, confirmation form, etc.
If the request is non-idempotent, but the target page is idempotent, just send a redirect after POST (i.e. return outcome with ?faces-redirect=true from action method, or manually invoke ExternalContext#redirect(), or put <redirect/> in legacy XML navigation case).
For example, showing list of all data after successful editing, redirect after login, etc.
Note that pure page-to-page navigation is usually idempotent and this is where many JSF starters fail by abusing command links/buttons for that and then complain afterwards that URLs don't change. Also note that navigation cases are very rarely used in real world applications which are developed with respect to SEO/UX and this is where many JSF tutorials fail by letting the readers believe otherwise.
Also note that using POST is absolutely not "more secure" than GET because the request parameters aren't immediately visible in URL. They are still visible in HTTP request body and still manipulatable. So there's absolutely no reason to prefer POST for idempotent requests for the sake of "security". The real security is in using HTTPS instead of HTTP and checking in business service methods if currently logged-in user is allowed to query entity X, or to manipulate entity X, etc. A decent security framework offers annotations for this.
See also:
What is the difference between redirect and navigation/forward and when to use what?
JSF implicit vs. explicit navigation
What URL to use to link / navigate to other JSF pages
Bookmarkability via View Parameters feature
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
When should I use h:outputLink instead of h:commandLink?
Creating master-detail pages for entities, how to link them and which bean scope to choose
Retaining GET request query string parameters on JSF form submit
Pass an object between #ViewScoped beans without using GET params

How to link to another liferay page

I'm trying to figure out how to link to another page within the same liferay site.
Obviously I could hardcode the url in my portlet's view but I'm worried about having to update all of my portlets in case the friendly url changes in the future.
I know the name of the page I'm trying to link to, but what if the page name changes too?
I've found infinity of classes that have methods that return friendlyUrls, such as PortalUtil, LayoutLocalServiceUtil, and even LayoutFriendlyURLLocalServiceUtil, but they all require parameters that I'm not sure how to obtain.
Is there a standard way of obtaining friendly urls in liferay?
If you want to link to another Page, you can either use LayoutId or friendly url names.
Both are unique for each companyId, so you are going to be pretty safe using them.
You can set the friendlyUrl as a PortletConfig parameters, so you can set them on portlet Level, and you won't have them hard-coded in your Portlet. Alternatively, you can also save them as custom params in portal-ext.properties (will apply for all portlets of that portal).
Now, that's a lot of code for this, so if you're dealing with specific problems, like creating Portlet Configuration or Reading portal-ext.properties, or creating renderUrls programatically, you should start new questions

How to navigate in JSF? How to make URL reflect current page (and not previous one)

I am currently learning JSF and was rather amazed and puzzled when I realized that whenever we use <h:form>, the standard behavior of JSF is to always show me the URL of the previous page in the browser, as opposed to the URL of the current page.
I understand that this has to do with the way JSF always posts a form to the same page and then just renders whatever page the controller gives it back to the browser which doesn't know the page location has changed.
It seems like JSF has been around for long enough that there must be a clean, solid way to deal with this. If so, would you mind sharing?
I have found various workarounds, but sadly nothing that seems like a real solid solution.
Simply accept that the URL is misleading.
Append "?faces-redirect=true" to the return value of every bean's action and then
figure out how to replace #RequestScoped with something else (Flash Scopes, CDI conversation, #SessionScoped, ...).
accept to have two HTTP round trips for every user action.
Use some method (e.g. 3rd party library or custom code) to hide the page name in the URL, always using the same generic URL for every page.
If "?faces-redirect=true" is as good as it gets, is there a way do configure an entire application to treat all requests this way?
Indeed, JSF as being a form based application targeted MVC framework submits the POST form to the very same URL as where the page with the <h:form> is been requested form. You can confirm it by looking at the <form action> URL of the generated HTML output. This is in web development terms characterized as postback. A navigation on a postback does by default not cause a new request to the new URL, but instead loads the target page as content of the response. This is indeed confusing when you merely want page-to-page navigation.
Generally, the right approach as to navigation/redirection depends on the business requirements and the idempotence (read: "bookmarkability") of the request (note: for concrete code examples, see the "See also" links below).
If the request is idempotent, just use a GET form/link instead of POST form (i.e. use <a>, <form>, <h:link> or <h:button> instead of <h:form> and <h:commandXxx>).
For example, page-to-page navigation, Google-like search form, etc.
If the request is non-idempotent, just show results conditionally in the same view (i.e. return null or void from action method and make use of e.g. <h:message(s)> and/or rendered).
For example, in-page data entry/edit, multi-step wizard, modal dialog, confirmation form, etc.
If the request is non-idempotent, but the target page is idempotent, just send a redirect after POST (i.e. return outcome with ?faces-redirect=true from action method, or manually invoke ExternalContext#redirect(), or put <redirect/> in legacy XML navigation case).
For example, showing list of all data after successful editing, redirect after login, etc.
Note that pure page-to-page navigation is usually idempotent and this is where many JSF starters fail by abusing command links/buttons for that and then complain afterwards that URLs don't change. Also note that navigation cases are very rarely used in real world applications which are developed with respect to SEO/UX and this is where many JSF tutorials fail by letting the readers believe otherwise.
Also note that using POST is absolutely not "more secure" than GET because the request parameters aren't immediately visible in URL. They are still visible in HTTP request body and still manipulatable. So there's absolutely no reason to prefer POST for idempotent requests for the sake of "security". The real security is in using HTTPS instead of HTTP and checking in business service methods if currently logged-in user is allowed to query entity X, or to manipulate entity X, etc. A decent security framework offers annotations for this.
See also:
What is the difference between redirect and navigation/forward and when to use what?
JSF implicit vs. explicit navigation
What URL to use to link / navigate to other JSF pages
Bookmarkability via View Parameters feature
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
When should I use h:outputLink instead of h:commandLink?
Creating master-detail pages for entities, how to link them and which bean scope to choose
Retaining GET request query string parameters on JSF form submit
Pass an object between #ViewScoped beans without using GET params

Resources