ActionRequest vs RenderRequest - liferay

I've read here that actionrequest is only valid during the action phase and RenderRequest is only valid during the render phase. However if I set actionREquest.setAttribute("object", myobject) I can access this object from my JSP, which I understand is the render phase right? How is this possible and how does this fit with the answer I link?

While ActionRequest and RenderRequest are distinct classes/objects, they all relate to the same request handling cycle. The main difference is that ActionRequest allows you to change state, RenderRequest does not any more.
While only one portlet on the page can handle an action (per single HTTP request), all portlets on the page typically render to make up the whole markup of the page. That's what the separation of action/render brings you in the portlet world. Servlets didn't have this because one servlet was always meant to render the whole page on every single request anyway. Portlets can render (which they most often do) and they can change state (which they typically do in the action phase)

You shouldn't forget that after an action-phase, portlet lifecycles proceed toward render-phase.
Try to watch the image in this blog post (the first I found by a google search): http://haitaoblog.blogspot.it/2011/05/portlets-portal.html
So JSP can access to both attributes in request.
On the other hand, if you need to access in the render phase to an action RENDER parameter, you have to set it inside your action code
actionResponse.setRenderParameter("parameter-name", "value");

Related

When does mojarra adds a naming container to the list of optional parameters?

In the source of the class AjaxBehaviorRenderer (line 260) there is a line that apparently appends the NamingContainer Id to the list of optional parameters of mojarra.ab(...). I've never come across it so I'm curious as to when it is used:
RenderKitUtils.appendProperty(ajaxCommand, "com.sun.faces.namingContainerId", namingContainerId, true);
line 260
While working on spec issue 790 last week, which should solve a.o. Rendering other form by ajax causes its view state to be lost, how do I add this back?, this was explained to me by Neil Griffin, a portlet guy.
It appears that portlets can have multiple JSF views rendering to the same HTML document, each with its own view state. In portlets, there's a special UIViewRoot instance which implements NamingContainer. During regular rendering, all forms, inputs and commands will have IDs and names prefixed with the view's own client ID. This will work fine during synchronous postbacks. The portlet can this way identify the exact view to restore.
However, during asynchronous postbacks, the jsf.js will create a bunch of additional ajax-specific request parameters such as javax.faces.source, javax.faces.partial.event, etc. Those request parameter names are not prefixed with the view's own client ID. Therefore the portlet cannot associate them with a specific view. Hence the impl issue 3031.
There was another problem of view state identifiers in ajax responses not being properly namespaced this way. Therefore the portlet implementation had to customize the partial response writer in the so-called "JSF bridge". This will be taken into account during implementing spec issue 790. Instead of sniffing a "portlet environment" as in current implementation, there will be checks on UIViewRoot instanceof NamingContainer which is more flexible and portlet-independent. The Mojarra-specific com.sun.faces.namingContainerId will also be removed. Instead, this value will be rendered to <partial-response id="..."> so that the jsf.js can just extract from there.
All in all, not really important if you're only targeting servlet based environments.
As per balusC comment :
It's only interesting for portlet based apps (not servlet based apps).
I can't exactly explain why and what it is used for (a portlet/liferay
guy might), but the portlet specific feature is called "namespaced
parameters". See https://web.liferay.com/web/meera.success/blog/-/blogs/liferay-requires-name-spaced-parameters

How to get ActionRequest and ActionResponse in Render Phase on Liferay portlet?

how can I get ActionRequest and ActionResponse in Render Phase on Liferay portlet? I tried to add ActionRequest and ActionResponse params to my method:
#RenderMapping()
public String renderForm(#ModelAttribute MyForm form, BindingResult result, ActionRequest request, ActionResponse response)
But these params causes exception:
Current request is not of type [javax.portlet.ActionRequest]
Thanks.
I like to give some explanation of requests.
PortletRequest/ActionRequest/RenderRequest
PortletRequest
The PortletRequest is the parent of both. An ActionRequest and a RenderRequest are both different types of PortletRequest objects.
ActionRequest
An ActionRequest is valid during the action processing phase of the portlet. During this phase, the portlet hasn't completely decided how it is going to render itself, be it minimized, maximized, in edit mode or in veiw mode, etc.
RenderRequest
On the other hand, the RenderRequest is valid during the rendering phase of the portlet. At this point, the portlet knows how it is going to render itself, and certain changes such as window state, are not allowed.
So, all those request/response have different significance.
In your case, You can retrieve prameter in render phase by using getParameter but need to set value in action phase by using setRenderParameter.
Note:
Portlet Specification (JSR 286 (Portlet 2.0))
major features of JSR 286 are:
Inter-Portlet Communication through events and public render parameters
Serving dynamically generated resources directly through portlets
Thanks.
ActionRequest and ActionResponse are tied to the action phase of portlet execution and can't be accessed during the render phase. During the render phase, only RenderRequest and RenderResponse are accessible. There's no such thing as an action request during a render phase.
If you want to access parameters from the action phase, use render parameters or the means of inter portlet communication.
A common practice is to set a render parameter during the action phase:
actionResponse.setRenderParameter("myParameter", "alligator");
In the render phase, you can read it from the render request:
renderRequest.getParameter("alligator");
For the means of inter portlet communication, see https://www.liferay.com/community/wiki/-/wiki/Main/Portlet+to+Portlet+Communication .

Send parameter from Portlet doView to portal_normal.vm

I'm trying to send a parameter from Portlet doView function to portal_normal.vm
Is it possible? How can I send and receive it?
Sorry, but I can't see the way to do through request.
In doView I wrote
HttpServletRequest httpRequest = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(renderRequest));
httpRequest.setAttribute("hola", "hola");
And in the portal normal I tried with:
#set ($holas =$request.get('attributes').get('hola'))
#set ($holas2 = $request.getSession().getAttribute("hola"))
$holas
$holas2
but Velocity only shows $holas $holas2
This sounds like an overly specific plan to display some information outside of the portlet - but also well outside the portlet spec. Is it possible? Yes. Does it have limitations? Yes.
I didn't try it, but I'd argue that you don't have any guarantee that all render phases of all portlets have been finished before portal_normal.vm starts to be evaluated. Technically it's only necessary to have them finished once they are actually about to render. Render is not allowed to change any state - and you're implying that in your case it might do - because on render something else will be displayed.
It might make sense to rather assume that your theme has some DOM element that is available on the page. Then render some javascript that manipulates this DOM element. The dependency on the theme is the same, but you could also fall back to some default rendering in case you can't find the DOM element.
Alternatively, if you insist on your mode of operation. you might try to go through the servlet-session (portlet session won't help) as you have access to the HttpServletRequest from portal_normal.vm. Be warned though: Access to HttpServletRequest is nonstandard and not really portal-thinking

Liferay: what is the relationship and difference between ActionRequest, RenderRequest and PortletRequest?

What is the relationship and difference between ActionRequest, RenderRequest and PortletRequest?
Can we get instance of one from another?
The PortletRequest is the parent of both. An ActionRequest and a RenderRequest are both different types of PortletRequest objects.
An ActionRequest is valid during the action processing phase of the portlet. During this phase, the portlet hasn't completely decided how it is going to render itself, be it minimized, maximized, in edit mode or in veiw mode, etc.
On the other hand, the RenderRequest is valid during the rendering phase of the portlet. At this point, the portlet knows how it is going to render itself, and certain changes such as window state, are not allowed.
If you want to pass the params from action to render, you would need to set the ActionResponse using
response.setRenderParameter(key,val);
Then this is available in the corresponding RenderRequest.
Answer was found here

What is the difference between doView() and render() functions in Liferay?

What is the actual difference between doView() and render() functions in Liferay? and also what is the difference between renderRequest and resourceRequest?
doView() = to handle render requests when in VIEW mode.
render() = This method invokes the doDispath() method and sets the title of the portlet by using getTitle() method. Then it invokes one of doView(), doEdit(), doHelp(), etc. depending of the portlet mode specified in the RenderRequest.
Again, RenderRequest is when you want to handle requests in the VIEW mode of the portlet. If your portlet uses additional resources to render the view (i.e. images, JavaScript files, etc.) then the JSP that renders the view will use <portlet:resourceURL /> tags to generate valid URLs to those resources. Those URLs will be processed with a pair of ResourceRequest and ResourceResponse objects.
You can override the resource phase though but bear in mind that when you use ResourceRequest/ResourceResponse to serve, the portlet can't change the current portlet mode, window state or render parameters. And also the parameters set on the resource urls are not the render parameters and they are valid to serve only that current resource request.

Resources