I am new to JSF (2).
In Struts we can invoke an action from a URL like app.action
. This invokes an action and returns a result page, say a JSP (initially there is no JSP/HTML).
How can the same thing be done in JSF? (I know how to invoke an action from an .xhtml) I.e. invoking a managed bean directly from a URL and getting a result page.
The pattern you're asking about is not really native to the way JSF works.
Request-based frameworks like Struts and Spring MVC, and the older Model-2 Servlet/JSP based approach did work like this.
In JSF, first and foremost it's the page (view) that's automatically mapped to a request URL. There's no notion of a bean that's directly mapped to a URL and also there's no notion of a bean that has a framework enforced 1:1 relation with a view. There is the concept of a backing bean though, but this is by convention. For JSF, all beans are "helper beans" that are merely referenced by the view.
BalusC outlined the popular ways that can be used today to get some of the behavior from request-based frameworks in JSF in his answer. JSF 2.2 will slightly expand on this support via the introduction of view actions, which formalizes a few of the typical use cases for the preRenderViewEvent
.
That said, JSF is a very flexible framework and very few things are set in stone. A lot of JSF's behavior can be replaced or added to via an elaborate plug-in and decorator system.
For this use case, the fact that JSF binds URLs to (Facelets) views can be overridden, and you can in fact let beans directly react to requests. Although for a slightly different purpose, this is what I essentially did for JavaVDL, by overriding the so-called view handler.
You do have to ask yourself if this is really what you want to do, and if you want to work in this way whether JSF is the best choice for you. But via the methods outlined in JavaVDL (sourcecode here), you should be able to do this. Do note that this last method is not suited for beginners and requires quite a lot of JSF experience if you want to pull this off yourself. (If you, or anyone else would like to have this functionality, please consider creating an issue for it at the OmniFaces issues list).
If it's preparing data for an initial GET request, just do the job in (post)constructor of the request or view scoped managed bean associated with the page.
@ManagedBean
@RequestScoped
public class Bean {
public Bean() {
// Here.
}
@PostConstruct
public void init(){
// Or here, certainly if you rely on injected dependencies like @EJB.
}
}
If it's controlling the request/response and may possibly redirect/navigate to another page, then do the job in preRenderView
.
<f:event type="preRenderView" listener="#{bean.listener}" />
with
public void listener() {
// ...
// You want to redirect?
externalContext.redirect(newURL);
// Or you want to navigate?
navigationHandler.handleNavigation(context, null, "newOutcome");
}
Or if you want to hook on all requests, then use a filter:
@WebFilter("/*")
public class MyFilter implements Filter {
// ...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With