Actually the question needs clarification. So I've got two basic ideas on what you might want to do.
Simple sharing of information on one view
If you want to share information on the same view you can inject managed beans in each other with @ManagedProperty
. Just remember that injected bean whould not have a lesser scope than the bean it is injected into. Actually, if all you need is an article object then I don't see the reason to use two managed beans in your situation, but still, you can do it with
@ManagedBean
@RequestScoped
public class BaseBean {
private Article article;
@ManagedProperty(value="#{injectedBean}")
private InjectedBean injectedBean;
}
To initialize both properties of the managed beans that you want to be the same, you can use the init method annotated with @PostConstruct
(but there are many alternatives), like in here
@PostConstruct
public void init() {
Article article = new Article("Welcome");
this.article = article;
injectedBean.setArticle(article);
}
Share information between views
In this scenario the user selects an article he wants to edit on the first view and passes it around for the second view. In this scenario a user selectes an article he wants to manipulate on one page (welcome.xhtml
) and the actual manipulation happens on the other page (manipulation.xhtml
).
The common approach is that each page is baced up by its own bean, so in the abovementioned setup the 'base bean' will lose its injection. So, welcome.xhtml
view will use some article objects that popped up on that page from somewhere and pass it for manipulation to the second view on button click.
The beans will be the same with reagrd to the article object.
@ManagedBean
@RequestScoped
public class BaseBean {
private Article article;
}
@ManagedBean
@RequestScoped
public class InjectedBean {
private Article article;
}
And the actual passing will happen during the button click, like in
<h:form>
<h:commandButton value="Manipulation" action="manipulation.xhtml">
<f:setPropertyActionListener target="#{injectedBean.article}" value="#{baseBean.article}"/>
</h:commandButton>
</h:form>
In the code, the property action listener method is instantiating a bean for the second view and sets it property with the property of a base bean.
Using get parameters for page loading
Sometimes it makes more sence not to include a command button to trigger navigation to the next view, but provide for a simple link to editing the page. It may be achieved by using <f:param>
tag. There are two basic ways of handling parameters in JSF: by using page actions / preRenderView
events or by injecting them directly in your managed beans with @ManagedProperty
.
- Using Page actions /
preRenderView
events
The job will be done by the target view
<f:metadata>
<f:viewParam id="articleId" name="articleId" value="#{injectedBean.id}" />
<f:event type="preRenderView" listener="#{injectedBean.initEvent}" />
</f:metadata>
for preRenderView
event and
<f:metadata>
<f:viewParam id="articleId" name="articleId" value="#{injectedBean.id}" />
<f:viewAction action="#{injectedBean.initEvent}" />
</f:metadata>
for page action. The managed bean (InjectedBean
object) will have the following init method
public void initEvent() {
if (id == null) {
String message = "No id specified in request";
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(message));
return;
}
//use your service method to load the article
//article = articleService.findById(id);
//and add messages appropriately
}
- Using
@ManagedProperty
annotation
The job will be done by the following bean method, annotated with @PostConstruct
, and parameter dependency injection. Remember, for the setup to work the bean must be @RequestScoped
, but there are workaround for other bean scopes.
@ManagedProperty(value="#{param.articleId}")
private Integer id;
@PostConstruct
public void initPostConstruct() {
if (id == null) {
String message = "No id specified in request";
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(message));
return;
}
//use your service method to load the article
//article = articleService.findById(id);
//and add messages appropriately
}
Any way the bean will be initialized during the next view (manipulation.xhtml
). Extremely useful comparison of these two ways, provided by BalusC, can be found here.
Navigation to this view may be handled, for example, via a simple <h:link>
, like in
<h:link value="Manipulate" outcome="manipulation.xhtml" >
<f:param name="articleId" value="#{baseBean.article.id}" />
</h:link>