On 3/6/06, David Schlotfeldt <[EMAIL PROTECTED]> wrote:
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.
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

