myfaces-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Kito Mann <kito.m...@virtua.com>
Subject Re: [proposal] A new module for improved JSF-MVC inside MyFaces Project
Date Wed, 28 May 2014 16:08:32 GMT
My initial response is that this looks pretty cool. Not sure how it'll fit
in with the JCP plans for JAX-RS MVC, but I like it in the JSF world.

___

Kito D. Mann | @kito99 | Author, JSF in Action
Virtua, Inc. | http://www.virtua.com | JSF/Java EE training and consulting
http://www.JSFCentral.com | @jsfcentral
+1 203-998-0403

* Listen to the Enterprise Java Newscast: *http://w
<http://blogs.jsfcentral.com/JSFNewscast/>ww.enterprisejavanews.com
<http://ww.enterprisejavanews.com>*
* JSFCentral Interviews Podcast:
http://www.jsfcentral.com/resources/jsfcentralpodcasts/
* Sign up for the JSFCentral Newsletter: http://oi.vresp.com/?fid=ac048d0e17


On Wed, May 28, 2014 at 10:49 AM, Leonardo Uribe <lu4242@gmail.com> wrote:

> Hi
>
> I have finally had some time to get a functional prototype out. For
> the people interested, take a look at:
>
> https://github.com/lu4242/test-draft-actions-for-jsf
>
> The example does what we have discussed in this thread. This
> is only a draft, and the intention is give us a better idea about this.
> I have only tried it with MyFaces 2.2.3, but it should work with
> Mojarra too.
>
> I think for JSF 2.2 we cannot do anymore. It is possible to imagine
> other good tricks like a front controller and so on , but we need
> to change the spec for that.
>
> The prototype is far to be fully functional, but it is simple and
> clear enough to give the people an idea about what can be done
> and if it is worth to do it or not.
>
> To run the prototype, just download the code and type in the
> command line:
>
> mvn install
> cd examples
> mvn clean jetty:run
>
> look in localhost:8080
>
> The next step after take a look at the prototype is propose a
> vote to include it as a module for myfaces commons, but it will take
> some time before that.
>
> Please share your reactions about this. Your opinions are welcomed.
>
> regards,
>
> Leonardo Uribe
>
> 2014-05-23 14:49 GMT+02:00 Leonardo Uribe <lu4242@gmail.com>:
> > Hi
> >
> > DR>> *Regarding #{ma:sourceActionURL('renderOptions') : render the URL
> > of the action
> > DR>> How is the URL rendered? Through the RequestMapping of the method
> > as defined with the Bean?
> > DR>> And the attribute, params of the action defined are appended to the
> URL?
> >
> > Good question Dora.
> >
> > For #{ma:sourceActionURL(...)} the idea is call
> > viewHandler.getActionURL(...), append a custom query parameter called
> > 'oamva', and then call externalContext.encodeActionURL(...) , so the
> > final link could look like this:
> >
> > /myfaces-mvc-examples/sayhello.jsf?jfwid=-5tba0312z&amp;oamva=button
> >
> > In this case we are adding a query param to a url that will be used
> > later in a POST, I think it is justified the use of a query param for
> > the command activation. The only thing to take care here is be sure
> > that the target component should fulfit some strict conditions, by
> > security reasons. Anyway, without view state the POST will not work.
> >
> > Theoretically, only the client window and the action must be append in
> > the URL, the other parameters like the view state, the input and so on
> > must be provided by the user manually. After all, this is something of
> > "low level", you want to have some flexibility at the time of define
> > the parameters, for some users that could be important.
> >
> > For ma:getLink, it uses the same logic for h:link, which is in
> > org.apache.myfaces.shared.renderkit.html.util.OutcomeTargetUtils
> > method getOutcomeTargetHref(facesContext, target).
> >
> > DR>> For $.post with this URL, when its not appended with the
> > attribute or params, execute="@form" attribute of ma:defineAction is
> > not used.
> > DR>> Purpose of this attribute out of scope of jQuery post?
> >
> > A declaration of ma:defineAction component is always, always required,
> > without exceptions. This component will always decoded and its action
> > processed.
> >
> > Most of the time
> > $(document.getElementById("#{ma:parentFormId()}")).serialize() will do
> > the job of add all input fields in the current form, so in that sense
> > it works as an f:ajax request. In JSF no matter where the f:ajax
> > request is, all the input fields of the parent form are sent, no
> > matter what the "execute" parameter says. By 2.2 spec, you know you
> > should always provide javax.faces.ViewState and
> > javax.faces.ClientWindow, so I think that's clear enough. In that
> > sense, it works just like f:ajax, but there is no render response
> > phase, instead the action defines what to render. It is responsibility
> > of the user to send the proper parameters, of the components that will
> > be processed.
> >
> > DR>> *autocomplete is transient and hence its not required to update
> viewstate
> >
> > I don't get what do you want to say. This is different from a form
> > POST, this is a javascript POST, autocomplete doesn't have sense in
> > this case.
> >
> > DR>> Script integration via jQuery with action is flowless and awesome!
> >
> > That's the idea. Something easy to use and flexible enough to cover
> > those rare cases where you need to get your hands dirty with
> > javascript, but without break the nice part of JSF abstraction, which
> > is be independent of protocols.
> >
> > These days I haven't had enough time to get it done, but I hope in
> > this weekend to get something out and publish a draft on my Github
> > account, so the people interested can take a look and see if these
> > ideas are good enough and later vote for create a new module, with
> > something clear in mind. This is trial and error, and nothing is
> > certain, so no matter if something looks fancy or cool, a community
> > vote is required to move forward from that point.
> >
> > regards,
> >
> > Leonardo Uribe
> >
> > 2014-05-21 18:34 GMT+02:00 Dora Rajappan <dorarajappan@yahoo.com>:
> >>
> >> *Regarding #{ma:sourceActionURL('renderOptions') : render the URL of the
> >> action
> >> How is the URL rendered? Through the RequestMapping of the method as
> defined
> >> with the Bean?
> >> And the attribute, params of the action defined are appended to the URL?
> >>
> >> For $.post with this URL, when its not appended with the attribute or
> >> params, execute="@form" attribute of ma:defineAction is not used.
> >> Purpose of this attribute out of scope of jQuery post?
> >>
> >> *autocomplete is transient and hence its not required to update
> viewstate
> >>
> >> Script integration via jQuery with action is flowless and awesome!
> >>
> >> Regards,
> >> Dora Rajappa
> >>
> >> On Monday, May 19, 2014 9:13 PM, Leonardo Uribe <lu4242@gmail.com>
> wrote:
> >>
> >>
> >> Hi
> >>
> >> DR>> How about @ViewAction("/section1", action="exportExcel")
> >>
> >> It will not work because you can't change the annotation definition.
> >> In other words, we should make "action" parameter a reserved one.
> >> Also, the parameter by itself can have a converter or validator or a
> >> EL binding, so you need to define that too. That's why @ViewParam or
> >> something that define the parameter is required.
> >>
> >> regards,
> >>
> >> Leonardo
> >>
> >> 2014-05-15 14:30 GMT+02:00 Dora Rajappan <dorarajappan@yahoo.com>:
> >>> <a href="#{ma:getLink('/section1/mypage?action=exportExcel')}">Export
> >>> excel</a>  can work
> >>> when the definition is
> >>>  @ViewAction("/section1/*", action="exportExcel")
> >>> How about
> >>>  @ViewAction("/section1", action="exportExcel")
> >>> On Wednesday, May 14, 2014 12:01 AM, Dora Rajappan
> >>> <dorarajappan@yahoo.com>
> >>> wrote:
> >>> How will  <a href="#{ma:getLink('mypage?action=exportExcel')}">Export
> >>> excel</a>
> >>> work when ViewAction is not defined as
> >>>
> >>> @ViewAction(value="/sayhello.xhtml",
> >>>                          params= {
> >>>                              @ViewParam(name="action",
> >>> expectedValue="exportExcel")
> >>>                          })
> >>>    public void method3(@ViewParam String param1,
> >>> @ViewParam("someOther") Integer param2)
> >>>    {
> >>> but  as @ViewAction("/section1/*", action="exportExcel")
> >>> Is the latter not supported now?
> >>>
> >>> facelet function getLink for action processing is not a bad idea.
> >>> On Sunday, May 11, 2014 11:52 PM, Leonardo Uribe <lu4242@gmail.com>
> wrote:
> >>> Hi
> >>>
> >>> Ok, I think the idea about @ViewAction and @ViewParam is clear, I have
> >>> implemented a fast prototype and it works well, there is a lot of
> things
> >>> we
> >>> can do for improvement, however we should focus the attention in other
> >>> areas so we can give the module a better structure.
> >>>
> >>> The next thing we need is how to combine javascript with JSF,
> specifically
> >>> in cases like this:
> >>>
> >>> <input id="search"/>
> >>> <script type="text/javascript">
> >>>    $('#search').autocomplete({
> >>>        source: "#{some EL that return a link to an action goes here}"
> >>>    });
> >>> </script>
> >>>
> >>> The idea is provide an input box and then write some javascript lines
> to
> >>> make the component an autocomplete box, but the problem is we need to
> >>> provide
> >>> a URL that can be used to retrieve the values to fill the box. In my
> >>> opinion,
> >>> mix EL and javascript is the best in these cases, but things get
> complex
> >>> quickly when you need to provide parameters and so on. So I would like
> to
> >>> propose these facelet functions (better with examples):
> >>>
> >>>    <a href="#{ma:getLink('mypage?action=exportExcel')}">Export
> excel</a>
> >>>
> >>> and
> >>>
> >>>    <ma:defineLink id="mylink">
> >>>        <f:param name="action" value="renderMessage"/>
> >>>    </ma:defineLink>
> >>>
> >>>    <a href="#{ma:getLinkFrom('mylink')}">Render url from EL
> expression</a>
> >>>
> >>> #{ma:getLink(...)} work just like h:link but receives the outcome as
> >>> parameter.
> >>> The function append the request path and the client window id, so the
> >>> final
> >>> generated link will be something like this:
> >>>
> >>>
> >>>
> http://localhost:8080/myfaces-mvc-examples/sayhello.jsf?id=5&jfwid=1di8uhetf9&action=exportExcel
> >>>
> >>> #{ma:getLinkFrom(...)} just inject the link from a component that works
> >>> just
> >>> like h:link but it is just a wrapper, so the user can customize the
> >>> parameters,
> >>> when the EL function is called, the link is rendered taking the
> parameters
> >>> in the definition. The outcome by default is the page itself.
> >>>
> >>>
> >>> Please note this proposal is something different from the one that
> suggest
> >>> to
> >>> create the link just pointing to the method in the bean like
> >>> #{ma:getLink('mybean', 'mymethod', params)}. After thinking about it,
> the
> >>> problem with that approach is the difficulty to do the match between
> the
> >>> link
> >>> to generate and the method. EL does not consider annotated methods, so
> it
> >>> is
> >>> not possible to scan the annotations from the EL unless you do a bypass
> >>> over
> >>> CDI.
> >>>
> >>> I think the approach proposed is something simple to understand, and it
> >>> has
> >>> the advantage that you can isolate the declaration of the link from the
> >>> rendering, so the final javascript code will be easier to read.
> >>>
> >>> Finally we need something for the POST case, so the idea is append
> >>> something
> >>> like this:
> >>>
> >>>    <form action="#{ma:encodeActionURL()}"
> >>>          method="post"
> >>>          enctype="application/x-www-form-urlencoded">
> >>>        ....
> >>>    </form>
> >>>
> >>> #{ma:encodeActionURL()} do what h:form does for encode the action url.
> >>> Then,
> >>> it is responsibility of the user to provide the view state and client
> >>> window
> >>> token in the request as data, so the postback can be processed
> properly.
> >>> In this case, the idea is the view scope will be available, but the
> >>> component
> >>> tree state will not be updated when POST goes back to the client, so
> any
> >>> changes on the component tree in the action will be ignored.
> >>>
> >>> JSF does not make any difference between GET and POST, so viewParam
> will
> >>> work just the same. What defines a postback in JSF is if the view state
> >>> field is in the request or not. Theoretically, use #{ma:getLink(...)}
> >>> should
> >>> work too, but I think there are different cases.
> >>>
> >>> There is a contradiction in this case. Send a POST, provide the view
> state
> >>> token, do not restore the view but restore the view scope bean. The
> >>> problem
> >>> is
> >>> after you make changes on the view scope beans you need to save those
> >>> changes,
> >>> and that could mean update the view state token, even if the beans are
> >>> stored
> >>> in the server (remember the beans can be serialized, for example in a
> >>> cluster).
> >>>
> >>> If we take a look at the proposed goals:
> >>>
> >>> 1) possibility to use a normal JSF lifecycle for the first GET request
> >>> 2) allow action handling and custom response for POST actions
> >>> 3) normal action handling like in asp.net MVC + a EL util function to
> >>> generate the action URL
> >>>
> >>> we cannot really make number 2 exactly as POST actions. It doesn't fit
> >>> because
> >>> "... JSF's core architecture is designed to be independent of specific
> >>> protocols and markup. ...".
> >>>
> >>> Really the problem proposed in number 2 is not simple and we should
> >>> analyze
> >>> it
> >>> carefully. In which cases do we really need that kind of action
> handling?
> >>> If
> >>> we are thinking for example in a JSF component that defines an endpoint
> >>> with
> >>> a
> >>> custom response (for example a captcha component), we need a component
> >>> oriented
> >>> solution, something closer as what we have for ajax. What we have
> proposed
> >>> here with @ViewAction works in the case the user needs to define an
> >>> endpoint
> >>> at the "page" level.
> >>>
> >>> Really the big problem is how to hook the javascript code, so the
> updates
> >>> of
> >>> the view state on the client side can be properly chained. For example
> in
> >>> MyFaces there is a queue for all ajax request, but we need that the
> >>> actions
> >>> sent that requires update the view state can be synchronized with that
> >>> ajax queue too.
> >>>
> >>> I think what we have already is enough useful for a module. After all,
> we
> >>> don't need to solve all the problems at once.
> >>>
> >>> Suggestions are welcomed.
> >>>
> >>> regards,
> >>>
> >>> Leonardo Uribe
> >>>
> >>> 2014-05-05 0:05 GMT+02:00 Leonardo Uribe <lu4242@gmail.com>:
> >>>> Hi Thomas
> >>>>
> >>>> TA>> AFAIR now, your solutions seems to be just a replacement
for
> >>>> f:viewAction
> >>>> TA>> + allow different handlers via URL parameters.
> >>>> TA>> Its sound really lightweight and easy actually :)
> >>>> TA>> Does it cover all our requirements from the earlier mails?
> >>>> TA>>
> >>>>
> >>>> I think so, but we need to write some examples to be sure that the
> syntax
> >>>> cover
> >>>> all cases.
> >>>>
> >>>> Instead put a Front Controller on top of the lifecycle, we can go with
> >>>> this approach
> >>>> and provide some methods to call JSF algorithm inline. We already have
> >>>> some
> >>>> code in VDL.createComponent(...) that does inline compilation, so it
> >>>> is not really
> >>>> hard to write the necessary lines to do so (if the code is properly
> >>>> implemented
> >>>> of course). The idea could be provide something like:
> >>>>
> >>>> JSFUtils.generatePage("/mypage.xhtml", ....)
> >>>>
> >>>> and internally we call the algorithm, and deal with the potential
> >>>> problems.
> >>>>
> >>>> So, if the user really wants to go with a MVC framework and use JSF
as
> >>>> template
> >>>> engine, it will be as simple as write the adapter for the framework.
> >>>> We should not
> >>>> reinvent the wheel in this case. So, all other cases not supported by
> >>>> f:viewAction/f:viewParam, which should be very, very few, should be
> done
> >>>> writing
> >>>> a servlet or using an MVC framework like JAX-RS, and if necessary
> calling
> >>>> JSF at render time.
> >>>>
> >>>> The nice part about reuse f:viewAction logic is that is something
> >>>> proved, everybody
> >>>> knows how it works, we are just extending the syntax to define
> >>>> f:viewAction in
> >>>> a more familiar way. In practice we need to write a custom component
> >>>> extending
> >>>> UIViewAction, but that's something easy, I have already done it and
it
> >>>> works.
> >>>>
> >>>> That should cover most of the cases. There are other cases that are
> >>>> indirectly
> >>>> related to this one, but after some review, it doesn't seem to be so
> >>>> interesting
> >>>> or useful, or can be too complex to implement properly, so we need to
> >>>> wait and push
> >>>> it into the next spec. Sometimes less is more. Let's see what happen.
> >>>>
> >>>>>> Whats the syntax for multiple params? ->
> >>>>>> params="action=exportExcel&someOther=string"?
> >>>>>> Maybe we could think about a more typesafe and readable way.
e.g.
> >>>>>>
> >>>>>> @ViewAction(value="my.xhtml", params = {
> >>>>>>      @ViewParam(name="action", value="exportExcel"),
> >>>>>>      @ViewParam(name="someOther", value="string")
> >>>>>> })
> >>>>
> >>>> I was thinking about this:
> >>>>
> >>>>    @ViewAction(value="/sayhello.xhtml", params="action=exportExcel")
> >>>>    public void method3(@ViewParam String param1,
> >>>> @ViewParam("someOther") Integer param2)
> >>>>    {
> >>>>
> >>>> The method has two parts: one define the parameters that should be
> >>>> present
> >>>> and the other define the activation conditions, in this case, when
> >>>> action=exportExcel. Please note to make @ViewParam("someOther"), we
> >>>> need to associate value to the key name. So we could do something
> >>>> like this:
> >>>>
> >>>>    @ViewAction(value="/sayhello.xhtml",
> >>>>                          params= {
> >>>>                                @ViewParam(name="action",
> >>>> expectedValue="exportExcel")
> >>>>                          })
> >>>>    public void method3(@ViewParam String param1,
> >>>> @ViewParam("someOther") Integer param2)
> >>>>    {
> >>>>
> >>>> I think in this way it looks better. Thanks for the suggestion.
> >>>>
> >>>> regards,
> >>>>
> >>>> Leonardo
> >>>
> >>>
> >>>
> >>>
> >>
> >>
>

Mime
View raw message