JBoss.orgCommunity Documentation
Beans that are deployed to a CDI container will automatically be registered with Errai and exposed to your GWT client application. So, you can use Errai to communicate between your GWT client components and your CDI backend beans. There are several very easy-to-use options:
Wiring up your GWT application with the CDI event subsystem
RPC style invocations on beans through a typed interface
Access beans in a publish/subscribe manner
Further, Errai enables you to make use of CDI producer methods and fields in your GWT client!
Any CDI managed component may produce and consume
events
. This allows beans to interact in a completely decoupled fashion. Beans consume events by registering for a particular event type and optional qualifiers. The Errai CDI extension simply extends this concept into the client tier. A GWT client application can simply register an
Observer
for a particular event type and thus receive events that are produced on the server-side. Likewise and using the same API, GWT clients can produce events that are consumed by a server-side observer.
Let's take a look at an example.
Example 2.1. FraudClient.java
public class FraudClient extends LayoutPanel {
@Inject
private Event<AccountActivity> event; (1)
private HTML responsePanel;
�
public FraudClient() {
super(new BoxLayout(BoxLayout.Orientation.VERTICAL));
}
@PostConstruct
public void buildUI() {
Button button = new Button("Create activity", new ClickHandler() {
public void onClick(ClickEvent clickEvent) {
event.fire(new AccountActivity());
}
});
responsePanel = new HTML();
add(button);
add(responsePanel);
}
public void processFraud(@Observes @Detected Fraud fraudEvent) { (2)
responsePanel.setText("Fraud detected: " + fraudEvent.getTimestamp());
}
}
Two things are noteworthy in this example:
Injection of an
Event
dispatcher proxy
Creation of an
Observer
method for a particular event type
The event dispatcher is responsible for sending events created on the client-side to the server-side event subsystem (CDI container). This means any event that is fired through a dispatcher will eventually be consumed by a CDI managed bean, if there is an corresponding
Observer
registered for it on the server side.
In order to consume events that are created on the server-side you need to declare an client-side observer method for a particular event type. In case an event is fired on the server this method will be invoked with an event instance of type you declared.
To complete the example, let's look at the corresponding server-side CDI bean:
Example 2.2. AccountService.java
@ApplicationScoped
public class AccountService {
�
@Inject @Detected
private Event<Fraud> event;
public void watchActivity(@Observes AccountActivity activity) {
Fraud fraud = new Fraud(System.currentTimeMillis());
event.fire(fraud);
}
}
A server can address a single client in response to an event by using
@Conversational
. Consider a service that responds to a subscription event. Naturally, only the newly subscribed client should receive the response.
Example 2.3. SubscriptionService.java
@ApplicationScoped
public class SubscriptionService {
�
@Inject
private Event<Documents> welcomeEvent;
@Conversational
public void onSubscription(@Observes Subscription subscription) {
Document docs = createWelcomePackage(subscription);
welcomeEvent.fire(docs);
}
}
When choosing RPC style invocations on beans, you basically rely on a typed java interface the CDI managed bean needs to expose. A GWT client component can then create an invocation proxy based on this interface. For more information see chapter on RPC mechanism .
If you choose publish/subscribe then your CDI bean needs to implement the
MessageCallback
interface, as described in chapter
Messaging
. Any bean exposed in this way can be accessed through the
MessageBuilderAPI
.
Producer methods and fields act as sources of objects to be injected. They are useful when additional control over object creation is needed before injections can take place e.g. when you need to make a decision at runtime before an object can be created and injected.
Example 2.4. App.java
@EntryPoint
public class App {
�...
@Produces @Supported
public MyBaseWidget createWidget() {
return (Canvas.isSupported()) ? new MyHtml5Widget() : new MyDefaultWidget();
}
}
Example 2.5. MyComposite.java
@ApplicationScoped
public class MyComposite extends Composite {
�
@Inject @Supported
public MyBaseWidget widget;
...
}
For more information on CDI producers, see the CDI specification and the WELD reference documentation .