You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by David Bowers <vi...@gmail.com> on 2006/01/05 15:59:53 UTC

Re: user Digest 5 Jan 2006 04:13:43 -0000 Issue 6352

Thanks for the reply.  My long term goal is to transition to JSF.  We are
just starting to use it at my client, so it's a bit of a trial run, but I
think we will adapt it more full-scale eventually.  To start with, I want to
use JSF to develop new pages and new functionality.

When working on a new piece of functionality, I developed a backing bean
that worked as a standalone bean with some JSF pages.  Now I want to use
that functionality by "mixing" it with some Struts pages.  For example, I
have a tiled page that renders a bunch of data that is pre-populated by a
Struts Action -- typical Struts usage.  Now I want to display the
information managed by my JSF managed bean in another part of my page.  When
I do something like this in pure Struts, I like to chain Struts actions
together, having each Action populate a certain subset of data, as this
helps keep my actions more decoupled and reusable.  Now that I'm trying to
integrate functionality from a JSF managed bean, I want to be able to add a
functionality from a JSF backing bean to the action chain, before passing
control to the faces servlet.

        <!--This is the original Struts action that pulled something
from the database
            Note that originally this passed control to a non-JSF tile def.-->
        <action
                path="/bookmarkable" class="com.example.SomeBookmarkableAction>
            <forward name="success" path="/something.do"/>
            <!-- Old forward <forward name="success"
path="/someTileDef.tiles"/> -->
        </action>
        <!-- This is how I'd like to integrate my Struts action chain
with JSF.
             #{someBean.someAction} will initialize a different set of
data for me, and then
             forward control to the tile definition (defined in
faces-config.xml).
             I will modify the jsp in the tile def to be JSF compatible, putting
             f:verbatim around all the old struts parts. -->
        <action
                path="/something">
            <forward name="success" path="#{someBean.someAction}"/>
        </action>


So that explains the integration side of things. In the example above, I am
not trying to get a page rendered in JSF to post back to a Struts action.
My migration strategy is to build new functionality in JSF, so I'm more
concerned with how to navigate from the old Struts world to JSF than the
other way around.

The other thing my proposed solution helps with is that it allows for a
bookmarkable JSF URL.  This has been the most difficult thing for me to
understand in JSF.  If you go to a JSF URL, and want to execute some
initialization logic *before* the JSP rendering begins, you have to use
something like Shale, and its prerender() call, or you have to put a getter
on a backing bean and put something like this at the start of you JSP page
to call it:
     <h:inputHidden value="#{someBean.init}"/>

The 2nd one really bothers me after working with Struts for a while.  It
looks a lot like business logic, and I don't like it in my JSP; and I don't
even have the option of forwarding control to a different page depending on
some other value.  I would use Shale, but I've already exceeded my new
technology quota at my client, and introducting a product still in
alpha-phase would not be wise.  The ability to forward from a Struts action
to a JSF method-binding solves this problem quite neatly in my mind, (until
I refill my political capital enough to introduce something like Shale :)
):  it gives me a bookmarkable URL, allows initialization logic to execute
before JSP rendering starts, allows me to take advantage of JSF managed
beans (3 cheers for dependency injection from multiple contexts), and allows
me to take advantage of JSF components in JSP.

I was critical of the Struts-faces JSF components because when I tried them
in a short test, I got an error trying to mix standard JSF tags (myfaces
implementation) like h:commandLink with the Struts components.  Maybe it was
just a temporary bug or a configuration problem, but since I do not need my
JSF pages to pass control back to a Struts action, except through a straight
link, I didn't see the benefit of using the struts-faces components.



On 5 Jan 2006 04:13:43 -0000, user-digest-help@struts.apache.org <
user-digest-help@struts.apache.org> wrote:
>
> ---------- Forwarded message ----------
> From: Craig McClanahan <cr...@apache.org>
> To: Struts Users Mailing List <us...@struts.apache.org>
> Date: Wed, 4 Jan 2006 16:17:54 -0800
> Subject: Re: [struts-faces] forwarding managed-bean event handler
> On 1/4/06, David Bowers <vi...@gmail.com> wrote:
> >
> > Unless I'm missing something big, the struts-faces library doesn't
> > address the concern I was talking about.
> > Struts-faces allows a jsp page that uses JSF components to post back
> > to a Struts Action, and it allows events
> > from JSF components to be handled by Struts actions (albeit very
> > awkwardly, since I think you have to use
> > JSF components from the struts-faces library).
>
>
> The awkwardness comes primarily from the fact that you end up with two
> controller frameworks that have *lots* of redundant features.  The
> frustration of trying to make this non-awkward is what led me to the
> conclusion that Shale would be *much* easier to build, and understand,
> because it eliminates all the redundancies :-).
>
> I've looked at the code for Struts-faces several times, (as
> > documentation seems pretty scarce)
> > and it seems to me like its scope is pretty limited.  That's why I'm
> > looking at other options for integration.
>
>
> It's not clear what your long term goals are ... if you don't want to use
> JSF components, then the only thing you seem to want to leverage from JSF
> is
> the binding expressions?  If that is actually the case, in the short term
> I
> would solve the problem a different way by building a custom ActionForward
> that has some non-EL based mechanism to do the "poor man's prerender call"
> :-), and dispense with JSF entirely.
>
> Once you get the ability to run on a JSP 2.1 container (Java EE 5), you'll
> have more flexibility ... the EL processing logic has been extracted out
> into its own spec, and you'll be able to use it programmatically without
> involving JSF.  But that will be then, and this is now, so that is not
> likely to help you much in the short term.
>
> Craig
>
>

Re: user Digest 5 Jan 2006 04:13:43 -0000 Issue 6352

Posted by Craig McClanahan <cr...@apache.org>.
On 1/5/06, David Bowers <vi...@gmail.com> wrote:
>
> Thanks for the reply.  My long term goal is to transition to JSF.  We are
> just starting to use it at my client, so it's a bit of a trial run, but I
> think we will adapt it more full-scale eventually.  To start with, I want
> to
> use JSF to develop new pages and new functionality.


Thanks for the explanation ... it really helps to understand where you're
coming from.  Some thoughts below.

When working on a new piece of functionality, I developed a backing bean
> that worked as a standalone bean with some JSF pages.  Now I want to use
> that functionality by "mixing" it with some Struts pages.  For example, I
> have a tiled page that renders a bunch of data that is pre-populated by a
> Struts Action -- typical Struts usage.  Now I want to display the
> information managed by my JSF managed bean in another part of my
> page.  When
> I do something like this in pure Struts, I like to chain Struts actions
> together, having each Action populate a certain subset of data, as this
> helps keep my actions more decoupled and reusable.


When you get to the "pure JSF" side on your new functionality, you'll want
to take a look at the Dialogs feature of Shale as well.  The corresponding
notion there is called an action state -- which is expressed as a method
binding in a manner pretty similar to what you're trying to do here :-).
And you can chain multiple action states together between view states if you
want to, as well as navigate differently depending on what an action state
actually returns (with Dialogs, both action states and view states return
outcome strings, somewhat like a Struts action returning ActionForwards,
that are used to drive transition to the next state).

  Now that I'm trying to
> integrate functionality from a JSF managed bean, I want to be able to add
> a
> functionality from a JSF backing bean to the action chain, before passing
> control to the faces servlet.
>
>         <!--This is the original Struts action that pulled something
> from the database
>             Note that originally this passed control to a non-JSF tile
> def.-->
>         <action
>                 path="/bookmarkable" class="
> com.example.SomeBookmarkableAction>
>             <forward name="success" path="/something.do"/>
>             <!-- Old forward <forward name="success"
> path="/someTileDef.tiles"/> -->
>         </action>
>         <!-- This is how I'd like to integrate my Struts action chain
> with JSF.
>              #{someBean.someAction} will initialize a different set of
> data for me, and then
>              forward control to the tile definition (defined in
> faces-config.xml).
>              I will modify the jsp in the tile def to be JSF compatible,
> putting
>              f:verbatim around all the old struts parts. -->
>         <action
>                 path="/something">
>             <forward name="success" path="#{someBean.someAction}"/>
>         </action>


I see what you're after now.

You can easily write custom code in a RequestProcessor or ActionForward
subclass that programmatically evaluates EL expressions (either value
bindings or method bindings), but they will *only* work when there is a
FacesContext lying around for the current request.  Because the request in
this case originally came in through the Struts controller servlet, that
won't be the case.  You'd have to do the steps that FacesServlet normally
does to set one up, before trying to process these expressions -- the source
code for FacesServlet from MyFaces or the JSF RI would have the details.

So that explains the integration side of things. In the example above, I am
> not trying to get a page rendered in JSF to post back to a Struts action.
> My migration strategy is to build new functionality in JSF, so I'm more
> concerned with how to navigate from the old Struts world to JSF than the
> other way around.


If you don't need prerendering logic, you can just set up a forward to a
path like "/newpage.faces" instead of "/oldpage.jsp".

If you do need prerendering logic, it should be possible to do the above
plus use Shale's ViewController API on the backing bean associated with
"/newpage.jsp" -- it will trigger the prerender() method at the appropriate
spot.

The other thing my proposed solution helps with is that it allows for a
> bookmarkable JSF URL.  This has been the most difficult thing for me to
> understand in JSF.  If you go to a JSF URL, and want to execute some
> initialization logic *before* the JSP rendering begins, you have to use
> something like Shale, and its prerender() call, or you have to put a
> getter
> on a backing bean and put something like this at the start of you JSP page
> to call it:
>      <h:inputHidden value="#{someBean.init}"/>
>
> The 2nd one really bothers me after working with Struts for a while.  It
> looks a lot like business logic, and I don't like it in my JSP; and I
> don't
> even have the option of forwarding control to a different page depending
> on
> some other value.


I agree with you.

  I would use Shale, but I've already exceeded my new
> technology quota at my client, and introducting a product still in
> alpha-phase would not be wise.  The ability to forward from a Struts
> action
> to a JSF method-binding solves this problem quite neatly in my mind,
> (until
> I refill my political capital enough to introduce something like Shale :)
> ):  it gives me a bookmarkable URL, allows initialization logic to execute
> before JSP rendering starts, allows me to take advantage of JSF managed
> beans (3 cheers for dependency injection from multiple contexts), and
> allows
> me to take advantage of JSF components in JSP.


You can get the bookmarkable URLs by using redirects instead of forwards in
your navigation rules, but that'll make a prerendering event even more
important.  Without Shale, your hidden field widget might make a good enough
solution for the short term.  It also gives you a good technical argument to
introduce Shale later ... to get rid of those hacks in your JSP pages :-).

I was critical of the Struts-faces JSF components because when I tried them
> in a short test, I got an error trying to mix standard JSF tags (myfaces
> implementation) like h:commandLink with the Struts components.  Maybe it
> was
> just a temporary bug or a configuration problem, but since I do not need
> my
> JSF pages to pass control back to a Struts action, except through a
> straight
> link, I didn't see the benefit of using the struts-faces components.


The integration library doesn't help your use case much at all.  It was more
intended for the migration scenario where an existing app would be modified,
one (entire) page at a time, to use JSF components instead of Struts HTML
tags, without affecting the back end actions or action forms.  The approach
you describe sounds like a better one for your needs.

Craig