What is the best way to bind a non-managed bean to an xPage? We use xPages controller classes in java, and would like to limit some classes to a specific xPage without using managed bean in faces-config.
Tried to use dataContext and some of the methods work, but we are not able to get the document data source, using resolveVariable method. It always returns doc=null. The same java class as a managed bean returns the data source correct.
Are there better ways to connect a bean to a specific xPage?
You can connect your Java controller with an XPage in beforePageLoad event:
<xp:this.beforePageLoad><![CDATA[#{javascript:
viewScope.controller = new com.yourdomain.controller.MyController();
controller.beforePageLoad()}]]>
</xp:this.beforePageLoad>
Then you can call methods of your controller using EL like this:
#{controller.save}
or you can connect certain events with your controller:
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
afterPageLoad="#{controller.afterPageLoad}"
Your controller has access to document data source.
public void save() throws Exception {
DominoDocument doc = (DominoDocument) JsfUtil.resolveVariable("currentDocument");
System.out.println("save(" + doc.getDocument().getUniversalID() + ")");
}
Related
I've a data table as below:
<h:dataTable value="#{bean.items}" var="item">
I'd like to populate it with a collection from the database obtained from a service method so that it is immediately presented when the page is opened during an initial (GET) request. When should I call the service method? And why?
Call it before page is loaded. But how?
Call it during page load. How?
Call it in the getter method. But it is called multiple times.
Something else?
Do it in bean's #PostConstruct method.
#ManagedBean
#RequestScoped
public class Bean {
private List<Item> items;
#EJB
private ItemService itemService;
#PostConstruct
public void init() {
items = itemService.list();
}
public List<Item> getItems() {
return items;
}
}
And let the value reference the property (not method!).
<h:dataTable value="#{bean.items}" var="item">
In the #PostConstruct you have the advantage that it's executed after construction and dependency injection. So in case that you're using an EJB to do the DB interaction task, a #PostConstruct would definitely be the right place as injected dependencies would not be available inside a normal constructor yet. Moreover, when using a bean management framework which uses proxies, such as CDI #Named, the constructor may or may not be called the way you expect. It may be called multiple times during inspecting the class, generating the proxy, and/or creating the proxy.
At least do not perform the DB interaction job in the getter, unless it's lazy loading and you really can't do anything else. Namely, it would be invoked during every iteration round. Calling the service method during every iteration round is plain inefficient and may end up in "weird" side effects during presentation and postbacks, such as old values from DB seemingly still sticking around in the model instead of new submitted values.
If you rely on GET request parameters, then use <f:viewParam> and <f:viewAction> instead. See also Creating master-detail pages for entities, how to link them and which bean scope to choose.
If you want to preserve the model (the items property) across postbacks on the same view (e.g. CRUD table/dialog), then make the bean #ViewScoped, else the model won't be in sync with the view when the same model is concurrently edited elsewhere. See also Creating master-detail table and dialog, how to reuse same dialog for create and edit.
If you utilize JPA's #Version feature on the model, then you can catch OptimisticLockException to deal with it and show a message like "The data has been edited by someone else, please refresh/review if the desired changes are as intended". See also Letting the presentation layer (JSF) handle business exceptions from service layer (EJB).
See also:
Why JSF calls getters multiple times
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
How to choose the right bean scope?
JSF Controller, Service and DAO
How can I get the posted form data in the backing component in the
processUpdates method?
#Override
public void processUpdates(FacesContext context) {
//get here rendered html code
}
Or can I get the posted form data in the decode method?
[Edit]:
My goal is to get the posted form data - Not to get the generated html code (Sry I wasn't precisely)
It is unclear what you want to achive, yet. I mean, at high level.
UIComponent.decode and processUpdates are medium-level lifecycle APIs which should be overriden when you want to extend the framework.
If you just need to use the framework, you need a managed bean, not a backing component.
Furthermore, generally only components that extend UIInput need to hook in those phases, because they are bound to a value="#{...}" value expression (which in turn refers to a managed bean, in most cases), and need to synchronize those values with the bound expression.
I suspect you are uselessly complicating your life: hooking into medium or low-level APIs is a real pain if you don't have an excellent understanding about how the framework operates.
Anyway, the standard request parameters decode into input component is this:
String clientId = this.getClientId(context);
Map<String, String> requestMap = context.getExternalContext().getRequestParameterMap();
String newValue = requestMap.get(clientId);
if (newValue != null)
{
this.setSubmittedValue(newValue);
}
Please, post the full xhtml facelet code (not the composite one, but the facelet using that composite), so I can understand where you want to go and I can try to point you to the right tool to use.
I've a data table as below:
<h:dataTable value="#{bean.items}" var="item">
I'd like to populate it with a collection from the database obtained from a service method so that it is immediately presented when the page is opened during an initial (GET) request. When should I call the service method? And why?
Call it before page is loaded. But how?
Call it during page load. How?
Call it in the getter method. But it is called multiple times.
Something else?
Do it in bean's #PostConstruct method.
#ManagedBean
#RequestScoped
public class Bean {
private List<Item> items;
#EJB
private ItemService itemService;
#PostConstruct
public void init() {
items = itemService.list();
}
public List<Item> getItems() {
return items;
}
}
And let the value reference the property (not method!).
<h:dataTable value="#{bean.items}" var="item">
In the #PostConstruct you have the advantage that it's executed after construction and dependency injection. So in case that you're using an EJB to do the DB interaction task, a #PostConstruct would definitely be the right place as injected dependencies would not be available inside a normal constructor yet. Moreover, when using a bean management framework which uses proxies, such as CDI #Named, the constructor may or may not be called the way you expect. It may be called multiple times during inspecting the class, generating the proxy, and/or creating the proxy.
At least do not perform the DB interaction job in the getter, unless it's lazy loading and you really can't do anything else. Namely, it would be invoked during every iteration round. Calling the service method during every iteration round is plain inefficient and may end up in "weird" side effects during presentation and postbacks, such as old values from DB seemingly still sticking around in the model instead of new submitted values.
If you rely on GET request parameters, then use <f:viewParam> and <f:viewAction> instead. See also Creating master-detail pages for entities, how to link them and which bean scope to choose.
If you want to preserve the model (the items property) across postbacks on the same view (e.g. CRUD table/dialog), then make the bean #ViewScoped, else the model won't be in sync with the view when the same model is concurrently edited elsewhere. See also Creating master-detail table and dialog, how to reuse same dialog for create and edit.
If you utilize JPA's #Version feature on the model, then you can catch OptimisticLockException to deal with it and show a message like "The data has been edited by someone else, please refresh/review if the desired changes are as intended". See also Letting the presentation layer (JSF) handle business exceptions from service layer (EJB).
See also:
Why JSF calls getters multiple times
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
How to choose the right bean scope?
JSF Controller, Service and DAO
I'm working on a JSF webapp which purpose is to wrap a command-line program.
One of its main functionality is the ability to share a session between users (eg. for courses purpose), so that when an input is sent to an instance of the application, the output sent to every subscriber for this session.
As a result of this design, the webapp is mainly composed of a view-scoped bean which will request a controller of the command-line application.
It has also been chosen to identify a session with the URL fragment (eg. mydomain/myapp/#SESSIONID), so that anyone using the URL with the same fragment will share inputs and outputs, using its own instance of the view-scoped bean but sharing the same controller
In order to push results to all subscribers, I'm using Primefaces Push. Results are primarily text that has to be appened to the webapp's terminal, but some commands lead to the programmatic creation of a JSF component.
In order to handle this, I just render these components to a string that I send to all subscribers.
Then, I realized that in order to handle ajax requests from components (and from every subscriber), the associated UIComponent needs to be added to the UIViewRoot in the context of (don't know how to express this) each view-scope bean.
As a matter of fact, I first tried to bind a "common container" (a UIForm) to a property of the view scoped bean, in which I would put the programmatically created components, but I obviously had to face the chicken/egg issue #BalusC talks about in his blog, because the component was added again on each ajax request. Setting javax.faces.PARTIAL_STATE_SAVING to false didn't help either (I'm using MyFaces 2.2.5)
So, as somewhat of a workaround, when the controller needs to create a new component, it basically adds the id of the component to the data pushed (in a HashMap converted to Json), and all subscribers will trigger (back) a remoteCommand to its own instance of the view-scoped bean, in order to update the "common container" from its own UIViewRoot.
This does work, but I don't like this way of doing it!
So:
would it be possible to handle this kind of sharing between view-scope beans (with the same name) which are stored in different HTTP sessions? I'm refering to this answer from #BalusC... maybe playing with javax.faces.ViewState - would it even be possible?
Is there a "magical" scope for my currently-view-scoped bean I could use?
Shall I rather use a completely different design?
Thanks!
If you want share data between all your application users you can use application scope.
If you still want to use view scope, you can connect your view scope with another application scope like this:
ApplicationView appView = BeanUtil.findBean("applicationView", FacesContext.getCurrentInstance());
import javax.faces.context.FacesContext;
public class BeanUtil {
#SuppressWarnings("unchecked")
public static <T> T findBean(String beanName, FacesContext context) {
return (T) context.getApplication().evaluateExpressionGet(context,
"#{" + beanName + "}", Object.class);
}
}
I am new to JSF and managed beans. I have a managed bean with some private property with public setter and Getter methods. Now when I add the managed bean's properties to JSF forms, should I add the private methods directly or should I use call the property by Getter methods?
For example:
<h:inputText value="#{BeanName.userName}"/>
<h:inputText value="#{BeanName.getUserName()}"/>
Which one is correct in above?
Assuming that you're using JBoss EL or EL 2.2+, both ways would work fine in the initial display. But the first one is actually more correct because the second one would only get the value, but never set the value. If you want to collect input values, you should always go for the first way. The EL (Expression Language) will then automatically locate the getUserName() and setUserName() methods whenever needed.
The second way will never work when you're using standard JSF EL implementation since it doesn't support direct method calls.
To learn more about JSF, start at our JSF wiki page.
If in your java class you have something like
....
private String coolStuff;
public String getCoolStuff() {
return coolStuff;
}
....
Then in your jsf page you access it like so:
#{myBackingBean.coolStuff}
The framework automatically looks for a method called getCoolStuff()
Hope that helps
number 1 is correct from above it is the private field that you connect if you are using EL with JSF in your form.
You still need the getter and the setter which the managed bean calls to get the values so you can save them in a database ....etc