[jsr362-observers:] [jsr362-experts:] Re: Thoughts about parameters
- From: Neil Griffin <
- Subject: [jsr362-observers:] [jsr362-experts:] Re: Thoughts about parameters
- Date: Tue, 30 Jul 2013 09:05:49 -0400
- List-id: <jsr362-experts.portletspec3.java.net>
Thanks so much for sending the email below. I spent some time this past week
developing some test portlets and asking Liferay's core product team for
feedback about the proposals.
On Jul 24, 2013, at 3:57 AM, Martin Scott Nicklous
> I mentioned in the call yesterday that I had been thinking about portlet
> parameter handling. I'd like to jot down some of my thoughts and get your
> feedback on them.
> JSR 286 parameters are string-based and modeled after servlet parameters.
> Public parameters are managed by the container and can be shared with other
> portlets. By "managed by the container" I mean that they can be ignored by
> the portlet programmer until they are needed and they won't go away. They
> can be read, set, and removed when needed, but they don't have to be
> explicitly tacked on to each URL or response in order to have them
> available. Private parameters describe the portlet private state. These
> parameters are "managed by the portlet" in that the programmer must
> explicitly set the private render parameters on each URL (with the
> exception of the Resource URL) and response, otherwise they disappear. As
> a portlet programmer you are forced to think of to private parameters as
> being attached to a StateAwareResponse or to a URL. Programmers have to
> spend considerable effort in handling the portlet state represented by the
> private render parameters. If in some special case you forget to set a
> parameter on the response or when creating a URL, "poof" it's gone, even if
> it was present on the request being processed. I find this to be
> counter-intuitive and error-prone.
> In fact, a very common portlet programming error is to forget to copy or
> set the parameters during request processing. One experienced and very
> excellent portlet programmer related to me that the following scenario
> catches him again and again: You write a portlet, obtain some input from
> the user, get some data from a back-end somewhere, setting your parameters
> all the way. Life is good. Then you add eventing. In some abstruse case
> during event processing, you forget to copy the parameters from the event
> request to the event response. "Poof" the parameters are gone, and your
> portlet breaks. Since it only happens during interaction with other
> portlets and even then only under certain circumstances, the bug can be
> really difficult to find.
I have never experienced this "poof it's gone" problem before, so I wrote a
test portlet that did the following:
1) In processAction:
a) Call ActionResponse.setRenderParameter("myParam1", "1")
b) Call ActionResponse.setEvent(name, value)
2) In processEvent:
a) Output EventRequest.getParameter("myParam1")
3) In doView:
a) Output RenderRequest.getParameter("myParam1")
Sure enough, in Pluto, the behavior was as you described, meaning the output
of 2a was "1" but the output of 3a was null.
But in Liferay, the value of both 2a and 3a was "1". So I suppose that this
behavior is an implementation detail. I guess that's why I never experienced
the problem before.
> Another very counter-intuitive characteristic of the JSR 286 API is setting
> or removing a public render parameter on an action URL. Action URLs and
> render URLs are both modeled as PortletURL objects, so the methods for
> manipulating the public render parameters are available on both action URLs
> and render URLs. However, if you try to remove a public render parameter
> from an action URL - nothing happens. You don't get an error, but the
> public render parameter stays put - it is not affected. If you try to set a
> public render parameter to a new value, again you don't get an error.
> However, rather than changing the public render parameter, you get a
> private parameter with the same name as the public render parameter so that
> when the URL is activated, you have both a private parameter AND a public
> parameter with the same name but probably different values. I can't imagine
> many cases where that would be the expected behavior. Again, for me this
> is completely counter-intuitive. And it can lead to the type of problem
> where a programmer says, "Well, I KNOW I set it, I can see it right here in
> the trace from my processAction method", however, no other portlet using
> that shared parameter can see the value change. Call up <your company> -
> public render parameters is broken!
> (The parameter behavior on the ResourceURL is very, very double-plus
> counter-intuitive - both the private and the public parameters are treated
> like the public parameters on the action URL - maybe we should fix that,
> too, but that is not the main subject of this post).
> We need to change how we think about parameters. It's good to have
> string-based parameters as we do now. It's good to have both public and
> private render parameters. However, ALL parameters should be "managed by
> the container" in the sense described above. The basic idea would be that
> once the parameters are set, they stay set, until the portlet explicitly
> changes them. And that would hold for private as well as for public render
> That would have the following implications for version 3 portlets (the
> container would still have to managed version 2 portlets in the same manner
> as they are currently handled).
> * For the StateAwareResponse it would look like the private parameters
> would be "automatically copied" from the request to the response, just as
> the public render parameters are "automatically copied" under the version 2
> model. This would happen for both the action request and the event request.
> We could add a container runtime parameter to turn the automatic copying
> off for people who like it the old way, or to allow version 2 portlets to
> be migrated more easily to the version 3 model.
I asked Liferay's core product team for feedback on this, and the consensus
was that they were not in favor of automatic copying of URL parameters from
the ACTION_PHASE into the EVENT_PHASE and RENDER_PHASE.
Also, automatic copying would seem to collide with Section 188.8.131.52 of the JSR
329 Spec regarding the function of ExternalContext.getRequestParameterMap(),
Specifically, Section 4.1 of the JSR 329 Spec states the following regarding
the javax.portlet.faces.preserveActionParams initialization parameter:
"When this initialization parameter isn't present or is false the action's
request parameters are only maintained for the duration of the portlet
request (ActionRequest) scope."
Regarding the "poof it's gone" problem, automatic copying of parameters from
the ACTION_PHASE into the EVENT_PHASE and RENDER_PHASE would be OK, as long
as it were limited to parameters that were explicitly set by the portlet
developer via StateAwareResponse.setRenderParameter(String, String).
> * For URL creation, it might be best to leave the current createActionURL()
> and createRenderURL() methods unchanged and add new methods something like
> createActionURL(boolean copyParameters) and createRenderURL(boolean
> copyParameters) that allow the current parameter settings to be
> automatically copied to the new URLs.
If the behavior of copyParameters=true was restricted to adding parameters to
the resulting URL that were explicitly set with
StateAwareResponse.setRenderParameter(String, String), then these new method
overloads would be OK.
> * And to get rid of my pet peeve - I think with regards to parameter
> handling, the action URL should be handled the same as the render URL.
> I think that these changes would make writing portlets much easier and more
> intuitive. I wonder if you think so, too ....