You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by David Schlotfeldt <tc...@plauditdesign.com> on 2006/03/07 02:22:25 UTC

action link

I need a way to have a URL that will cause a JSF action to take place. 
Anyone know of a way? (For an example, lets say I need to put the link 
in an email.)

All I find are "hackerish" javascript solutions to this issue.

Would it be possible to create a version of the commandLink that didn't 
need a form around it and didn't use javascript? Obviously it couldn't 
include any information from form fields but that is okay with me.

Or would it be possible to create a servelet filter that converts a 
normal request to a request JSF wants?
      Eg. We have a form with a field called 'name' and a button called 
'sayHi'. With the filter I could send a person to a url like 
http://test.com/page-form-is-on.html?link=sayHi&name=David
    The filter would take the request and convert convert the params 
into what JSF wants. I don't know how to do this... except maybe make a 
fake request in the fitler to the JSF for the form to get jsf_state_64 
and jsf_tree_64 values and then send the request on with the request 
parameters rewritten.

Suggestions? Anyone know of a good solution?   (...other than mine that 
would take me 3 weeks, 4 days, and 7382 Red Bulls...)
         


Re: action link

Posted by Craig McClanahan <cr...@apache.org>.
On 3/7/06, David Schlotfeldt <tc...@plauditdesign.com> wrote:
>
> I have written a new way to solve this issue with the idea I described
> below. After receiving responses to my original post I was going to use
> NonFacesRequestServlet but realized that it wouldn't do any validation.
> (At least I am PERTTY sure it doesn't. Someone correct me if I am wrong.)
>
> What I have done is created a servlet filter that can be used to make it
> seem as if a person has already loaded the page and has filled it out
> and clicked a link or button. -- simply by requesting a URL. What I did
> is a servlet filter that makes a request to the JSF page, searches the
> response for form fields, and then merges those fields default values
> with the request parameters from the real request. It then calls
> doChain(...) with a wrapped http request that has all the values from
> the form and the real request. This makes it possible to seem as if
> someone went to the page and clicked a button or link. (In fact it does
> happen, but the filter does it.)
>
> For example the following url can be used on an order form I am creating
> to cause the next button to be pushed.
> register.html?doReq=true&formId=placeOrder&placeOrder:next=true
>
> doReq=true triggers the fitler. FormId is the id of the form.
> PlaceOrder:next is a button I am causing to be pushed.


If I'm understanding you correctly, doesn't this mean you will never have
any JSF component state to restore, so that every request will seem like a
new request?  And therefore bypass the normal request processing lifecycle?
(Normally, in Restore View, if there is no state to restore, JSF will create
a new tree and then proceed directly to Render Response phase.)

I can see how it *might* work if you are using server side state saving, and
the view id that the external site sends back happens to be one for which
there was server side state, but you are skating on the thin ice of
implementation dependencies (rather than features that are defined by the
spec to be portable) here.

Craig

I did all of this because I have a multi step form with a step in the
> middle that is on another site. Using this filter I can make the
> external step send the user back to the JSF form and cause an action to
> take place when it comes back.
>
> What are peoples opinion on this approach?
> (I don't know how the API having to do with JSF's life cycle works so
> maybe its possible to do this type of thing from a servlet so a fake
> request doesn't have to be made.)
>
> Thanks,
> David
>
>
> David Schlotfeldt wrote:
> > I need a way to have a URL that will cause a JSF action to take place.
> > Anyone know of a way? (For an example, lets say I need to put the link
> > in an email.)
> >
> > All I find are "hackerish" javascript solutions to this issue.
> >
> > Would it be possible to create a version of the commandLink that
> > didn't need a form around it and didn't use javascript? Obviously it
> > couldn't include any information from form fields but that is okay
> > with me.
> >
> > Or would it be possible to create a servelet filter that converts a
> > normal request to a request JSF wants?
> >      Eg. We have a form with a field called 'name' and a button called
> > 'sayHi'. With the filter I could send a person to a url like
> > http://test.com/page-form-is-on.html?link=sayHi&name=David
> >    The filter would take the request and convert convert the params
> > into what JSF wants. I don't know how to do this... except maybe make
> > a fake request in the fitler to the JSF for the form to get
> > jsf_state_64 and jsf_tree_64 values and then send the request on with
> > the request parameters rewritten.
> >
> > Suggestions? Anyone know of a good solution?   (...other than mine
> > that would take me 3 weeks, 4 days, and 7382 Red Bulls...)
> >
>
>

Re: action link

Posted by Hubert Rabago <hr...@gmail.com>.
I took a different approach.  My filter calls methods which are
specifically written with the awareness that they will be called as a
non-faces request.  The intention is to avoid confusion over what
state is available when the method is triggered.  This would be useful
for URLs that can be emailed or launched from other applications, to
go directly to a page displaying specific data.

Right now it's configured with XML, but I'm in the process of
extracting out some of the logic into an interface that I can
reimplement to allow automapping in a way Craig does with his remoting
URLs.

The advantage of the XML is I can specify how the bean is set up,
independent of how it's configured in faces-config.xml:

<action path="/baz" action="#{foo.bar}">
    <property name="documentId" value="#{param.id}"/>
</action>

A request could be "/baz.jsf?id=1".

It prevents other fields from being auto-populated by a user
manipulating the URL.  In the "foo.bar" method, I know all I have is
"documentId" and none of the other properties, so I behave
accordingly.

Hubert

On 3/7/06, David Schlotfeldt <tc...@plauditdesign.com> wrote:
> I have written a new way to solve this issue with the idea I described
> below. After receiving responses to my original post I was going to use
> NonFacesRequestServlet but realized that it wouldn't do any validation.
> (At least I am PERTTY sure it doesn't. Someone correct me if I am wrong.)
>
> What I have done is created a servlet filter that can be used to make it
> seem as if a person has already loaded the page and has filled it out
> and clicked a link or button. -- simply by requesting a URL. What I did
> is a servlet filter that makes a request to the JSF page, searches the
> response for form fields, and then merges those fields default values
> with the request parameters from the real request. It then calls
> doChain(...) with a wrapped http request that has all the values from
> the form and the real request. This makes it possible to seem as if
> someone went to the page and clicked a button or link. (In fact it does
> happen, but the filter does it.)
>
> For example the following url can be used on an order form I am creating
> to cause the next button to be pushed.
> register.html?doReq=true&formId=placeOrder&placeOrder:next=true
>
> doReq=true triggers the fitler. FormId is the id of the form.
> PlaceOrder:next is a button I am causing to be pushed.
>
> I did all of this because I have a multi step form with a step in the
> middle that is on another site. Using this filter I can make the
> external step send the user back to the JSF form and cause an action to
> take place when it comes back.
>
> What are peoples opinion on this approach?
> (I don't know how the API having to do with JSF's life cycle works so
> maybe its possible to do this type of thing from a servlet so a fake
> request doesn't have to be made.)
>
> Thanks,
> David
>
>
> David Schlotfeldt wrote:
> > I need a way to have a URL that will cause a JSF action to take place.
> > Anyone know of a way? (For an example, lets say I need to put the link
> > in an email.)
> >
> > All I find are "hackerish" javascript solutions to this issue.
> >
> > Would it be possible to create a version of the commandLink that
> > didn't need a form around it and didn't use javascript? Obviously it
> > couldn't include any information from form fields but that is okay
> > with me.
> >
> > Or would it be possible to create a servelet filter that converts a
> > normal request to a request JSF wants?
> >      Eg. We have a form with a field called 'name' and a button called
> > 'sayHi'. With the filter I could send a person to a url like
> > http://test.com/page-form-is-on.html?link=sayHi&name=David
> >    The filter would take the request and convert convert the params
> > into what JSF wants. I don't know how to do this... except maybe make
> > a fake request in the fitler to the JSF for the form to get
> > jsf_state_64 and jsf_tree_64 values and then send the request on with
> > the request parameters rewritten.
> >
> > Suggestions? Anyone know of a good solution?   (...other than mine
> > that would take me 3 weeks, 4 days, and 7382 Red Bulls...)
> >
>
>

Re: action link

Posted by David Schlotfeldt <tc...@plauditdesign.com>.
I have written a new way to solve this issue with the idea I described 
below. After receiving responses to my original post I was going to use 
NonFacesRequestServlet but realized that it wouldn't do any validation. 
(At least I am PERTTY sure it doesn't. Someone correct me if I am wrong.)

What I have done is created a servlet filter that can be used to make it 
seem as if a person has already loaded the page and has filled it out 
and clicked a link or button. -- simply by requesting a URL. What I did 
is a servlet filter that makes a request to the JSF page, searches the 
response for form fields, and then merges those fields default values 
with the request parameters from the real request. It then calls 
doChain(...) with a wrapped http request that has all the values from 
the form and the real request. This makes it possible to seem as if 
someone went to the page and clicked a button or link. (In fact it does 
happen, but the filter does it.)

For example the following url can be used on an order form I am creating 
to cause the next button to be pushed.
register.html?doReq=true&formId=placeOrder&placeOrder:next=true

doReq=true triggers the fitler. FormId is the id of the form. 
PlaceOrder:next is a button I am causing to be pushed.

I did all of this because I have a multi step form with a step in the 
middle that is on another site. Using this filter I can make the 
external step send the user back to the JSF form and cause an action to 
take place when it comes back.

What are peoples opinion on this approach?
(I don't know how the API having to do with JSF's life cycle works so 
maybe its possible to do this type of thing from a servlet so a fake 
request doesn't have to be made.)

Thanks,
David


David Schlotfeldt wrote:
> I need a way to have a URL that will cause a JSF action to take place. 
> Anyone know of a way? (For an example, lets say I need to put the link 
> in an email.)
>
> All I find are "hackerish" javascript solutions to this issue.
>
> Would it be possible to create a version of the commandLink that 
> didn't need a form around it and didn't use javascript? Obviously it 
> couldn't include any information from form fields but that is okay 
> with me.
>
> Or would it be possible to create a servelet filter that converts a 
> normal request to a request JSF wants?
>      Eg. We have a form with a field called 'name' and a button called 
> 'sayHi'. With the filter I could send a person to a url like 
> http://test.com/page-form-is-on.html?link=sayHi&name=David
>    The filter would take the request and convert convert the params 
> into what JSF wants. I don't know how to do this... except maybe make 
> a fake request in the fitler to the JSF for the form to get 
> jsf_state_64 and jsf_tree_64 values and then send the request on with 
> the request parameters rewritten.
>
> Suggestions? Anyone know of a good solution?   (...other than mine 
> that would take me 3 weeks, 4 days, and 7382 Red Bulls...)
>        


Re: action link

Posted by Mike Kienenberger <mk...@gmail.com>.
Yes, after I made the post, I realized that a link to shale's docs
would probably be more appropriate.  I added the link and the two-cent
description to our page for your motivation :)

=============
Also see Shale remoting for executing method binding expressions
specified by URLs.
http://struts.apache.org/struts-shale/features-remoting.html
=============

On 3/7/06, Craig McClanahan <cr...@apache.org> wrote:
> On 3/7/06, Mike Kienenberger <mk...@gmail.com> wrote:
>
> > Hey Craig,
> >
> > Are you willing to update the wiki to also include your ideas on using
> > Shale remoting for this?
>
>
>  Actually, the first place this needs to go is on the Shale web site page
> describing remoting[1], which is ... umm ... slightly content-light at the
> moment :-).  Then we can point at it from the MyFaces Wiki.
>
>  Craig
>
>  [1]
> http://struts.apache.org/struts-shale/features-remoting.html
>
>
> > Currently the wiki page only contains this Shale info, and nothing
> > about remoting:
> >
> >
> http://wiki.apache.org/myfaces/InvokingJsfPagesWithStandardUrls
> > =================
> > Use Struts Shale
> >
> > Apparently the Struts Shale library for JSF has a ViewController class
> > that provides useful functionality for accessing these params.
> > =================
> >
> > On 3/6/06, Craig McClanahan <cr...@apache.org> wrote:
> > >
> > >
> > >
> > > On 3/6/06, David Schlotfeldt <tc...@plauditdesign.com> wrote:
> > > > I need a way to have a URL that will cause a JSF action to take place.
> > > > Anyone know of a way? (For an example, lets say I need to put the link
> > > > in an email.)
> > > >
> > > > All I find are "hackerish" javascript solutions to this issue.
> > > >
> > > > Would it be possible to create a version of the commandLink that
> didn't
> > > > need a form around it and didn't use javascript? Obviously it couldn't
> > > > include any information from form fields but that is okay with me.
> > >
> > >
> > >  Isn't that basically what <h:outputLink> (instead of <h:commandLink>)
> does?
> > >  The only question then becomes how to figure out the appropriate URL
> (to
> > > which you can attach query parameters as necessary).
> > >
> > >  This is the same kind of problem that AJAX components have when they
> want
> > > to trigger server side handlers asynchronously.  See below for one
> approach
> > > to this.
> > >
> > >
> > > > Or would it be possible to create a servelet filter that converts a
> > > > normal request to a request JSF wants?
> > > >       Eg. We have a form with a field called 'name' and a button
> called
> > > > 'sayHi'. With the filter I could send a person to a url like
> > > >
> > >
> http://test.com/page-form-is-on.html?link=sayHi&name=David
> > > >     The filter would take the request and convert convert the params
> > > > into what JSF wants. I don't know how to do this... except maybe make
> a
> > > > fake request in the fitler to the JSF for the form to get jsf_state_64
> > > > and jsf_tree_64 values and then send the request on with the request
> > > > parameters rewritten.
> > > >
> > > > Suggestions? Anyone know of a good solution?   (...other than mine
> that
> > > > would take me 3 weeks, 4 days, and 7382 Red Bulls...)
> > > >
> > > >
> > > >
> > >
> > >  Shale[1] includes a Remoting[2] feature that supports a version of this
> > > sort of functionality -- the significant restriction (at least for the
> > > current version) is that the server side code will not have access to
> the
> > > saved JSP component state, and therefore no access to the component
> tree.
> > > But, if you are using "*.faces" mappings for your JSF requests, and
> default
> > > mappings for Shale Remoting, a URL like this:
> > >
> > >      http://localhost:8080/myapp/dynamic/foo/bar.faces
> > >
> > >  will tell Shale Remoting to create a method binding expression "#{
> foo.bar}"
> > > and execute it.  This, in turn, causes the creation of a managed bean
> named
> > > "foo" (if you have defined it that way; otherwise the bean must already
> > > exist in some scope), and then a public method named bar() that takes no
> > > parameters and returns void is called.  This method is responsible for
> > > creating the entire HTTP response for this request, which it can do in a
> > > number of ways:
> > >
> > >  * Get a ResponseWriter (there's a convenient helper factory
> > >    included in Shale Remoting) and write XML/XHTML output
> > >    the same way that a component renderer would do it.
> > >
> > >  * Forward to a JSP page that creates the response
> > >
> > >  * Forward to a URL mapped to FacesServlet, and have
> > >    a JSF view create the response.
> > >
> > >  To handle request parameters inside the handler, you can call
> > > FacesContext.getExternalContext().getRequestParameterMap() and pull them
> out
> > > yourself.  Or, if you are using managed beans, you can let JSF do
> dependency
> > > injection for you.  Consider a managed bean named "handler" defined like
> > > this:
> > >
> > >      <managed-bean>
> > >          <managed-bean-name>handler</managed-bean-name>
> > >          <managed-bean-class>...your bean
> class...</managed-bean-class>
> > >
> <managed-bean-scope>request</managed-bean-scope>
> > >          <managed-property>
> > >              <property-name>name</property-name>
> > >              <value>#{param.name}</value>
> > >          </managed-property>
> > >      </managed-bean>
> > >
> > >  and a managed bean like this:
> > >
> > >      public class MyBean {
> > >          ...
> > >          public void setName(String name) { ... }
> > >          ...
> > >          public void sayHi() { ... }
> > >          ...
> > >      }
> > >
> > >  With this setup, a call to a URL like
> > >
> > >
> > >
> http://localhost:8080/myapp/dynamic/handler/sayHi?name=David
> > >
> > >  will cause Shale Remoting to create the bean in request scope, pass
> "David"
> > > to the setName() method, and then call your sayHi() function.  (In any
> given
> > > app, you can have as many different managed beans, and as many
> activatable
> > > methods on those beans, as you like.)
> > >
> > >  The documentation is a little light at the moment ... but start with
> the
> > > Package Description for package "org.apache.shale.remoting" on the
> second
> > > link below.  Also, you can take a look at the "Use Cases" example
> > > application for a worked-out example ... on the main menu, take a look
> at
> > > the "new-style remoting" links, and you'll see how they execute method
> > > binding expressions
> "#{remoting$business.listCategories}"
> > > and "#{remoting$business.listLocales}" respectively.
> These
> > > kinds of method calls are quite useful for asynchronous callbacks from
> AJAX
> > > client widgets, but (as you can see here) they work just fine as a
> standard
> > > request link too.
> > >
> > >  Craig
> > >
> > >  [1] http://struts.apache.org/struts-shale
> > >  [2]
> > >
> http://struts.apache.org/struts-shale/shale-remoting/apidocs/index.html
> > >
> > >
> >
>
>

Re: action link

Posted by Craig McClanahan <cr...@apache.org>.
On 3/7/06, Mike Kienenberger <mk...@gmail.com> wrote:
>
> Hey Craig,
>
> Are you willing to update the wiki to also include your ideas on using
> Shale remoting for this?


Actually, the first place this needs to go is on the Shale web site page
describing remoting[1], which is ... umm ... slightly content-light at the
moment :-).  Then we can point at it from the MyFaces Wiki.

Craig

[1] http://struts.apache.org/struts-shale/features-remoting.html

Currently the wiki page only contains this Shale info, and nothing
> about remoting:
>
> http://wiki.apache.org/myfaces/InvokingJsfPagesWithStandardUrls
> =================
> Use Struts Shale
>
> Apparently the Struts Shale library for JSF has a ViewController class
> that provides useful functionality for accessing these params.
> =================
>
> On 3/6/06, Craig McClanahan <cr...@apache.org> wrote:
> >
> >
> >
> > On 3/6/06, David Schlotfeldt <tc...@plauditdesign.com> wrote:
> > > I need a way to have a URL that will cause a JSF action to take place.
> > > Anyone know of a way? (For an example, lets say I need to put the link
> > > in an email.)
> > >
> > > All I find are "hackerish" javascript solutions to this issue.
> > >
> > > Would it be possible to create a version of the commandLink that
> didn't
> > > need a form around it and didn't use javascript? Obviously it couldn't
> > > include any information from form fields but that is okay with me.
> >
> >
> >  Isn't that basically what <h:outputLink> (instead of <h:commandLink>)
> does?
> >  The only question then becomes how to figure out the appropriate URL
> (to
> > which you can attach query parameters as necessary).
> >
> >  This is the same kind of problem that AJAX components have when they
> want
> > to trigger server side handlers asynchronously.  See below for one
> approach
> > to this.
> >
> >
> > > Or would it be possible to create a servelet filter that converts a
> > > normal request to a request JSF wants?
> > >       Eg. We have a form with a field called 'name' and a button
> called
> > > 'sayHi'. With the filter I could send a person to a url like
> > >
> > http://test.com/page-form-is-on.html?link=sayHi&name=David
> > >     The filter would take the request and convert convert the params
> > > into what JSF wants. I don't know how to do this... except maybe make
> a
> > > fake request in the fitler to the JSF for the form to get jsf_state_64
> > > and jsf_tree_64 values and then send the request on with the request
> > > parameters rewritten.
> > >
> > > Suggestions? Anyone know of a good solution?   (...other than mine
> that
> > > would take me 3 weeks, 4 days, and 7382 Red Bulls...)
> > >
> > >
> > >
> >
> >  Shale[1] includes a Remoting[2] feature that supports a version of this
> > sort of functionality -- the significant restriction (at least for the
> > current version) is that the server side code will not have access to
> the
> > saved JSP component state, and therefore no access to the component
> tree.
> > But, if you are using "*.faces" mappings for your JSF requests, and
> default
> > mappings for Shale Remoting, a URL like this:
> >
> >      http://localhost:8080/myapp/dynamic/foo/bar.faces
> >
> >  will tell Shale Remoting to create a method binding expression "#{
> foo.bar}"
> > and execute it.  This, in turn, causes the creation of a managed bean
> named
> > "foo" (if you have defined it that way; otherwise the bean must already
> > exist in some scope), and then a public method named bar() that takes no
> > parameters and returns void is called.  This method is responsible for
> > creating the entire HTTP response for this request, which it can do in a
> > number of ways:
> >
> >  * Get a ResponseWriter (there's a convenient helper factory
> >    included in Shale Remoting) and write XML/XHTML output
> >    the same way that a component renderer would do it.
> >
> >  * Forward to a JSP page that creates the response
> >
> >  * Forward to a URL mapped to FacesServlet, and have
> >    a JSF view create the response.
> >
> >  To handle request parameters inside the handler, you can call
> > FacesContext.getExternalContext().getRequestParameterMap() and pull them
> out
> > yourself.  Or, if you are using managed beans, you can let JSF do
> dependency
> > injection for you.  Consider a managed bean named "handler" defined like
> > this:
> >
> >      <managed-bean>
> >          <managed-bean-name>handler</managed-bean-name>
> >          <managed-bean-class>...your bean class...</managed-bean-class>
> >          <managed-bean-scope>request</managed-bean-scope>
> >          <managed-property>
> >              <property-name>name</property-name>
> >              <value>#{param.name}</value>
> >          </managed-property>
> >      </managed-bean>
> >
> >  and a managed bean like this:
> >
> >      public class MyBean {
> >          ...
> >          public void setName(String name) { ... }
> >          ...
> >          public void sayHi() { ... }
> >          ...
> >      }
> >
> >  With this setup, a call to a URL like
> >
> >
> > http://localhost:8080/myapp/dynamic/handler/sayHi?name=David
> >
> >  will cause Shale Remoting to create the bean in request scope, pass
> "David"
> > to the setName() method, and then call your sayHi() function.  (In any
> given
> > app, you can have as many different managed beans, and as many
> activatable
> > methods on those beans, as you like.)
> >
> >  The documentation is a little light at the moment ... but start with
> the
> > Package Description for package "org.apache.shale.remoting" on the
> second
> > link below.  Also, you can take a look at the "Use Cases" example
> > application for a worked-out example ... on the main menu, take a look
> at
> > the "new-style remoting" links, and you'll see how they execute method
> > binding expressions "#{remoting$business.listCategories}"
> > and "#{remoting$business.listLocales}" respectively.  These
> > kinds of method calls are quite useful for asynchronous callbacks from
> AJAX
> > client widgets, but (as you can see here) they work just fine as a
> standard
> > request link too.
> >
> >  Craig
> >
> >  [1] http://struts.apache.org/struts-shale
> >  [2]
> > http://struts.apache.org/struts-shale/shale-remoting/apidocs/index.html
> >
> >
>

Re: action link

Posted by Mike Kienenberger <mk...@gmail.com>.
Hey Craig,

Are you willing to update the wiki to also include your ideas on using
Shale remoting for this?

Currently the wiki page only contains this Shale info, and nothing
about remoting:

http://wiki.apache.org/myfaces/InvokingJsfPagesWithStandardUrls
=================
Use Struts Shale

Apparently the Struts Shale library for JSF has a ViewController class
that provides useful functionality for accessing these params.
=================

On 3/6/06, Craig McClanahan <cr...@apache.org> wrote:
>
>
>
> On 3/6/06, David Schlotfeldt <tc...@plauditdesign.com> wrote:
> > I need a way to have a URL that will cause a JSF action to take place.
> > Anyone know of a way? (For an example, lets say I need to put the link
> > in an email.)
> >
> > All I find are "hackerish" javascript solutions to this issue.
> >
> > Would it be possible to create a version of the commandLink that didn't
> > need a form around it and didn't use javascript? Obviously it couldn't
> > include any information from form fields but that is okay with me.
>
>
>  Isn't that basically what <h:outputLink> (instead of <h:commandLink>) does?
>  The only question then becomes how to figure out the appropriate URL (to
> which you can attach query parameters as necessary).
>
>  This is the same kind of problem that AJAX components have when they want
> to trigger server side handlers asynchronously.  See below for one approach
> to this.
>
>
> > Or would it be possible to create a servelet filter that converts a
> > normal request to a request JSF wants?
> >       Eg. We have a form with a field called 'name' and a button called
> > 'sayHi'. With the filter I could send a person to a url like
> >
> http://test.com/page-form-is-on.html?link=sayHi&name=David
> >     The filter would take the request and convert convert the params
> > into what JSF wants. I don't know how to do this... except maybe make a
> > fake request in the fitler to the JSF for the form to get jsf_state_64
> > and jsf_tree_64 values and then send the request on with the request
> > parameters rewritten.
> >
> > Suggestions? Anyone know of a good solution?   (...other than mine that
> > would take me 3 weeks, 4 days, and 7382 Red Bulls...)
> >
> >
> >
>
>  Shale[1] includes a Remoting[2] feature that supports a version of this
> sort of functionality -- the significant restriction (at least for the
> current version) is that the server side code will not have access to the
> saved JSP component state, and therefore no access to the component tree.
> But, if you are using "*.faces" mappings for your JSF requests, and default
> mappings for Shale Remoting, a URL like this:
>
>      http://localhost:8080/myapp/dynamic/foo/bar.faces
>
>  will tell Shale Remoting to create a method binding expression "#{foo.bar}"
> and execute it.  This, in turn, causes the creation of a managed bean named
> "foo" (if you have defined it that way; otherwise the bean must already
> exist in some scope), and then a public method named bar() that takes no
> parameters and returns void is called.  This method is responsible for
> creating the entire HTTP response for this request, which it can do in a
> number of ways:
>
>  * Get a ResponseWriter (there's a convenient helper factory
>    included in Shale Remoting) and write XML/XHTML output
>    the same way that a component renderer would do it.
>
>  * Forward to a JSP page that creates the response
>
>  * Forward to a URL mapped to FacesServlet, and have
>    a JSF view create the response.
>
>  To handle request parameters inside the handler, you can call
> FacesContext.getExternalContext().getRequestParameterMap() and pull them out
> yourself.  Or, if you are using managed beans, you can let JSF do dependency
> injection for you.  Consider a managed bean named "handler" defined like
> this:
>
>      <managed-bean>
>          <managed-bean-name>handler</managed-bean-name>
>          <managed-bean-class>...your bean class...</managed-bean-class>
>          <managed-bean-scope>request</managed-bean-scope>
>          <managed-property>
>              <property-name>name</property-name>
>              <value>#{param.name}</value>
>          </managed-property>
>      </managed-bean>
>
>  and a managed bean like this:
>
>      public class MyBean {
>          ...
>          public void setName(String name) { ... }
>          ...
>          public void sayHi() { ... }
>          ...
>      }
>
>  With this setup, a call to a URL like
>
>
> http://localhost:8080/myapp/dynamic/handler/sayHi?name=David
>
>  will cause Shale Remoting to create the bean in request scope, pass "David"
> to the setName() method, and then call your sayHi() function.  (In any given
> app, you can have as many different managed beans, and as many activatable
> methods on those beans, as you like.)
>
>  The documentation is a little light at the moment ... but start with the
> Package Description for package "org.apache.shale.remoting" on the second
> link below.  Also, you can take a look at the "Use Cases" example
> application for a worked-out example ... on the main menu, take a look at
> the "new-style remoting" links, and you'll see how they execute method
> binding expressions "#{remoting$business.listCategories}"
> and "#{remoting$business.listLocales}" respectively.  These
> kinds of method calls are quite useful for asynchronous callbacks from AJAX
> client widgets, but (as you can see here) they work just fine as a standard
> request link too.
>
>  Craig
>
>  [1] http://struts.apache.org/struts-shale
>  [2]
> http://struts.apache.org/struts-shale/shale-remoting/apidocs/index.html
>
>

Re: action link

Posted by Craig McClanahan <cr...@apache.org>.
On 3/6/06, David Schlotfeldt <tc...@plauditdesign.com> wrote:
>
> I need a way to have a URL that will cause a JSF action to take place.
> Anyone know of a way? (For an example, lets say I need to put the link
> in an email.)
>
> All I find are "hackerish" javascript solutions to this issue.
>
> Would it be possible to create a version of the commandLink that didn't
> need a form around it and didn't use javascript? Obviously it couldn't
> include any information from form fields but that is okay with me.


Isn't that basically what <h:outputLink> (instead of <h:commandLink>) does?
The only question then becomes how to figure out the appropriate URL (to
which you can attach query parameters as necessary).

This is the same kind of problem that AJAX components have when they want to
trigger server side handlers asynchronously.  See below for one approach to
this.

Or would it be possible to create a servelet filter that converts a
> normal request to a request JSF wants?
>       Eg. We have a form with a field called 'name' and a button called
> 'sayHi'. With the filter I could send a person to a url like
> http://test.com/page-form-is-on.html?link=sayHi&name=David
>     The filter would take the request and convert convert the params
> into what JSF wants. I don't know how to do this... except maybe make a
> fake request in the fitler to the JSF for the form to get jsf_state_64
> and jsf_tree_64 values and then send the request on with the request
> parameters rewritten.
>
> Suggestions? Anyone know of a good solution?   (...other than mine that
> would take me 3 weeks, 4 days, and 7382 Red Bulls...)
>
>
>
Shale[1] includes a Remoting[2] feature that supports a version of this sort
of functionality -- the significant restriction (at least for the current
version) is that the server side code will not have access to the saved JSP
component state, and therefore no access to the component tree.  But, if you
are using "*.faces" mappings for your JSF requests, and default mappings for
Shale Remoting, a URL like this:

    http://localhost:8080/myapp/dynamic/foo/bar.faces

will tell Shale Remoting to create a method binding expression "#{foo.bar}"
and execute it.  This, in turn, causes the creation of a managed bean named
"foo" (if you have defined it that way; otherwise the bean must already
exist in some scope), and then a public method named bar() that takes no
parameters and returns void is called.  This method is responsible for
creating the entire HTTP response for this request, which it can do in a
number of ways:

* Get a ResponseWriter (there's a convenient helper factory
  included in Shale Remoting) and write XML/XHTML output
  the same way that a component renderer would do it.

* Forward to a JSP page that creates the response

* Forward to a URL mapped to FacesServlet, and have
  a JSF view create the response.

To handle request parameters inside the handler, you can call
FacesContext.getExternalContext().getRequestParameterMap() and pull them out
yourself.  Or, if you are using managed beans, you can let JSF do dependency
injection for you.  Consider a managed bean named "handler" defined like
this:

    <managed-bean>
        <managed-bean-name>handler</managed-bean-name>
        <managed-bean-class>...your bean class...</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
        <managed-property>
            <property-name>name</property-name>
            <value>#{param.name}</value>
        </managed-property>
    </managed-bean>

and a managed bean like this:

    public class MyBean {
        ...
        public void setName(String name) { ... }
        ...
        public void sayHi() { ... }
        ...
    }

With this setup, a call to a URL like

    http://localhost:8080/myapp/dynamic/handler/sayHi?name=David

will cause Shale Remoting to create the bean in request scope, pass "David"
to the setName() method, and then call your sayHi() function.  (In any given
app, you can have as many different managed beans, and as many activatable
methods on those beans, as you like.)

The documentation is a little light at the moment ... but start with the
Package Description for package "org.apache.shale.remoting" on the second
link below.  Also, you can take a look at the "Use Cases" example
application for a worked-out example ... on the main menu, take a look at
the "new-style remoting" links, and you'll see how they execute method
binding expressions "#{remoting$business.listCategories}" and
"#{remoting$business.listLocales}" respectively.  These kinds of method
calls are quite useful for asynchronous callbacks from AJAX client widgets,
but (as you can see here) they work just fine as a standard request link
too.

Craig

[1] http://struts.apache.org/struts-shale
[2] http://struts.apache.org/struts-shale/shale-remoting/apidocs/index.html

Re: action link

Posted by David Schlotfeldt <tc...@plauditdesign.com>.
Perfect. I haven't tried this yet but I think this is exactly what I wanted.

Also thanks Craig McClanahan for your response.

David


Mike Kienenberger wrote:
> See this page for other ideas:
>
> http://wiki.apache.org/myfaces/InvokingJsfPagesWithStandardUrls
>
> The NonFacesRequestServlet seems particularly popular for solving this problem.
>
> On 3/6/06, David Schlotfeldt <tc...@plauditdesign.com> wrote:
>   
>> I need a way to have a URL that will cause a JSF action to take place.
>> Anyone know of a way? (For an example, lets say I need to put the link
>> in an email.)
>>
>> All I find are "hackerish" javascript solutions to this issue.
>>
>> Would it be possible to create a version of the commandLink that didn't
>> need a form around it and didn't use javascript? Obviously it couldn't
>> include any information from form fields but that is okay with me.
>>
>> Or would it be possible to create a servelet filter that converts a
>> normal request to a request JSF wants?
>>       Eg. We have a form with a field called 'name' and a button called
>> 'sayHi'. With the filter I could send a person to a url like
>> http://test.com/page-form-is-on.html?link=sayHi&name=David
>>     The filter would take the request and convert convert the params
>> into what JSF wants. I don't know how to do this... except maybe make a
>> fake request in the fitler to the JSF for the form to get jsf_state_64
>> and jsf_tree_64 values and then send the request on with the request
>> parameters rewritten.
>>
>> Suggestions? Anyone know of a good solution?   (...other than mine that
>> would take me 3 weeks, 4 days, and 7382 Red Bulls...)
>>
>>
>>
>>     
>
>   

Re: action link

Posted by Mike Kienenberger <mk...@gmail.com>.
See this page for other ideas:

http://wiki.apache.org/myfaces/InvokingJsfPagesWithStandardUrls

The NonFacesRequestServlet seems particularly popular for solving this problem.

On 3/6/06, David Schlotfeldt <tc...@plauditdesign.com> wrote:
> I need a way to have a URL that will cause a JSF action to take place.
> Anyone know of a way? (For an example, lets say I need to put the link
> in an email.)
>
> All I find are "hackerish" javascript solutions to this issue.
>
> Would it be possible to create a version of the commandLink that didn't
> need a form around it and didn't use javascript? Obviously it couldn't
> include any information from form fields but that is okay with me.
>
> Or would it be possible to create a servelet filter that converts a
> normal request to a request JSF wants?
>       Eg. We have a form with a field called 'name' and a button called
> 'sayHi'. With the filter I could send a person to a url like
> http://test.com/page-form-is-on.html?link=sayHi&name=David
>     The filter would take the request and convert convert the params
> into what JSF wants. I don't know how to do this... except maybe make a
> fake request in the fitler to the JSF for the form to get jsf_state_64
> and jsf_tree_64 values and then send the request on with the request
> parameters rewritten.
>
> Suggestions? Anyone know of a good solution?   (...other than mine that
> would take me 3 weeks, 4 days, and 7382 Red Bulls...)
>
>
>