integrating seam and gwt - jazoon · 6 seam overview(1/ 2) > a java framework – for building...
TRANSCRIPT
Integrating Seam and GWTIntegrating the JBoss Seam Framework with the GWT Toolkit :
Use cases and patterns
Ferda Tartanoglu
Neoxia
6563
2
Who we are
> Ferda TARTANOGLU, PhD
– Consultant and Software Architect at Neoxia
> Neoxia
– A consult ing company specialized in information system governance and architecture
– Based in France (Paris) and Morocco (Casablanca)
> The Seam/ GWT team
– Issam EL FATMI
– Nizar GARRACHE
– Mohamed Amine LIMEM
– Nicolas DASRIAUX
3
AGENDA
> Overview
> Introducing Seam
> Introducing GWT
> Why Integrate?
> Integrat ion Patterns
> Conclusion
4
Overview
> Web application for the company Intranet
> Integrating Seam and GWT
– Complementary technologies
> It is also an integration of GWT with Seam’s underlying technologies
– jBPM, JSF, Facelet, EJB3 ...
> Lessons learned
– Architectural principles
– Integrat ion patterns
Seam
Google Web Toolkit
jBPM JSF Facelet EJB3
5
AGENDA
> Overview
> Introducing Seam
> Introducing GWT
> Why Integrate?
> Integrat ion Patterns
> Conclusion
6
Seam overview(1/ 2)
> A Java framework– For building stateful Web applications– With or without Java EE
> Glue for integrating several technologies– Presentation layer with JSF, Facelets, Richfaces– Business logic and persistence with EJB3 and JPA– Business processes and workflows with jBPM– Business rules with Drools– Third party frameworks: Wicket, Spring, GWT…
> Provides advanced application security– Authentication– Identity management– Authorization
7
Seam architecture (2/ 2)
JSF components – Facelets - Richfaces
Seam components & contexts
jBPM JPAEJB3
Presentation
Request Controller
Context Management
Business LogicState Management
JSF
8
AGENDA
> Overview
> Introducing Seam
> Introducing GWT
> Why Integrate?
> Integrat ion Patterns
> Conclusion
9
GWT overview (1/ 2)
> GWT provides mainly a Java- to- Javascript compiler
– Code is writ ten in Java and is compiled to JavaScript
– Support for major browsers
> Rich user interface library
– GWT widgets
– Third party widgets
> Built- in Ajax
– No need to code in JavaScript
– Remoting based on the Servlet standard Server- side code written in Java as a Servlet
10
GWT model (2/ 2)
> Programming model
– Java with some restrict ions
– Event- based controller like Swing
– Asynchronous RPC for client- server communication
> Deployment model
– JavaScript for client- side computing Hosted on any Web server Executed on the user’s browser
– Java Servlet for server- side computing WAR packaging since v 1.6
11
AGENDA
> Overview
> Introducing Seam
> Introducing GWT
> Why Integrate?
> Integrat ion Patterns
> Conclusion
12
A Case Study
> An intranet business application with specif ic requirements
– Interactive UI Ajax !
– Security Authentication Secure communicat ion Role- based authorizat ions
– Workflows Long- running business processes with several part icipants
– Messaging Email
– Persistence Storage in MySQL database
– Transactions ACID transact ions on DB resources Atomicity and Isolat ion propert ies for mult i- page/ act ion interactive sessions
13
Overlapping Features of Seam & GWT
> Rich UI components
– JavaScript widgets support ing Ajax for GWT
– JSF components, Richfaces, JSF4Ajax for Seam
> Support for server- side computing
– JavaScript remoting with servlets for GWT
– Servlets or EJB beans for Seam
14
Differences of Seam & GWT
> Seam lacks
– Intuit ive Ajax widgets
– Lightweight and extensible UI component model
– JavaScript library for client side components
> GWT does not provide
– Support for stateful services
– Extended persistence context
– Global transactions
– Bookmarkable pages
– Support for security
– Templates
15
Integration Issues
> GWT
– Oriented single page stateless applications
– Uses a subset of the JDK
> Seam
– Oriented mult i- page stateful applications
– Some features rely on JSF
> We should try
– Using the benefits of each technologies
– Minimizing the integration effort
16
AGENDA
> Overview
> Introducing Seam
> Introducing GWT
> Why Integrate?
> Integration Patterns
> Conclusion
17
Integration Patterns
> GWT client side widget in a JSF page
> GWT as the presentation layer of Seam
> GWT and Seam navigation rules
> GWT in a Seam conversation
> Taking part in a Seam business process
> Seam Security and GWT
18
Integration Patterns
> GWT client side widget in a JSF page
> GWT as the presentation layer of Seam
> GWT and Seam navigation rules
> GWT in a Seam conversation
> Taking part in a Seam business process
> Seam Security and GWT
19
Pattern 1GWT widget in a JSF page (1/ 4)> Coexistance of GWT and JSF on the
same page
> Using Seam for facelet layouts and themes
> GWT widgets for complex components and screens
20
Pattern 1GWT widget in a JSF page (2/ 4)> JSF Page
<ui:define name="body">
<script language="javascript"
src=“com.neoxia.gwtseam.gwt.MyApplication.nocache.js"></script>
<rich:panel >
<h:panelGrid columns="2">
<s:div styleClass="info">
<table align="center">
<tr><td id="slot1"></td><td id="slot2"></td></tr>
</table>
</s:div>
</h:panelGrid>
</rich:panel>
</ui:define>
21
Pattern 1GWT widget in a JSF page (3/ 4)> JSF Page : content type<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<f:view contentType="text/html"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a="http://richfaces.org/a4j"
xmlns:s="http://jboss.com/products/seam/taglib">
<html>
(...)
22
Pattern 1GWT widget in a JSF page (4/ 4)> GWT client- side : The widgetpublic class AskQuestionWidget extends Composite {
(...)
}
> GWT client- side : The entry point– Binding the widget to the placeholder in the JSF page
public class MyApplication implements EntryPoint {
public void onModuleLoad() {
RootPanel.get("slot1").add(new AskQuestionWidget());
}
}
23
Integration Patterns
> GWT client side widget in a JSF page
> GWT as the presentation layer of Seam
> GWT and Seam navigation rules
> GWT in a Seam conversation
> Taking part in a Seam business process
> Seam Security and GWT
24
Pattern 2GWT as the presentation layer of Seam (1/ 6)> GWT as the only presentation layer
– No JSF page
– No JSF life cycle
> GWT widgets access to Seam components with asynchronous requests by JavaScript (Ajax)
25
Pattern 2GWT as the presentation layer of Seam (2/ 6)> Service interfaces
– The remote service interface
public interface MyService {
public String askIt(String question);
}
– GWT client- side asynchronous interface
public interface MyServiceAsync extends RemoteService {
public void askIt(String question, AsyncCallback callback);
}
26
Pattern 2GWT as the presentation layer of Seam (3/ 6)> GWT widget code
– The service stub to be used by the GWT client- side widget
private MyServiceAsync getService() {
MyServiceAsync svc =
(MyServiceAsync)GWT.create(MyService.class);
String endpointURL = GWT.getModuleBaseURL() +
"seam/resource/gwt";
((ServiceDefTarget)svc).setServiceEntryPoint(endpointURL);
return svc;
}
27
Pattern 2GWT as the presentation layer of Seam (4/ 6)> GWT client- side: The widget code
– The remote call
getService().askIt(text, new AsyncCallback<String>() {
public void onFailure(Throwable t) {
Window.alert(t.getMessage());
}
public void onSuccess(Object data) {
Window.alert((String) data);
}
});
28
Pattern 2GWT as the presentation layer of Seam (5/ 6)> Server- side Seam component
@Name(“com.neoxia.gwtseam.gwt.client.MyService")
public class ServiceImpl implements MyService {
@In Credentials credentials;
@WebRemote
public String askIt(String question) {
String username = credentials.getUsername();
return "Hello " + username;
}
}
29
Pattern 2GWT as the presentation layer of Seam (6/ 6)
GWT
Seam Remoting
Seam components & contexts
jBPM JPAEJB3
Presentation
Request Controller
Context Management
Business LogicState Management
30
Pattern 1 & 2GWT remoting + JSF
JSF components + GWT widgets
Seam Remoting
Seam components & contexts
jBPM JPAEJB3
Presentation
Request Controller
Context Management
Business LogicState Management
JSF
31
Integration Patterns
> GWT client side widget in a JSF page
> GWT as the presentation layer of Seam
> GWT and Seam navigation rules
> GWT in a Seam conversation
> Taking part in a Seam business process
> Seam Security and GWT
32
Pattern 3 GWT and Seam navigation rules (1/ 6)> We want to
– Describe the navigation process using Seam’s pages.xml or jPDL notation
– Make a remote call to a Seam component from GWT widget
– Get the URL or render page according to the outcome of the component method and the navigation process
33
Pattern 3GWT and Seam navigation rules (2/ 6)> Actions have outcomes
public String increment() { value++; return "success";}
> Navigation rules
<page view-id=“*"> <navigation> <rule if-outcome=“success"> <redirect view-id="/home.xhtml"/> </rule> </navigation></page>
34
Pattern 3GWT and Seam navigation rules (3/ 6)
> Seam navigation is based on JSF life cycle
> Seam remoting bypasses JSF servlet and accesses directly to the SeamResourceServlet
– No FacesContext
– No programmatic navigation API in Seam
> Methods called using Seam remoting return directly the output parameter, if any, to the caller
35
Pattern 3GWT and Seam navigation rules (4/ 6)> Re- implement JSF navigation layers in the remote service
– Tight integration, JSF- dependent
> Wait for Seam navigation to be promoted to the level of 1st class cit izenship
– JSF- independent navigation API that can be used with any presentation framework
> Workaround using 2 subsequent requests
– First request using remoting API
– Second request through JSF
36
Pattern 3GWT and Seam navigation rules (5/ 6)> The first method called through Seam Remotingpublic String increment() {
value++;
return "success";
}
> The second method called through JSF– The call is a standard JSF call, the method returns the same outcome
and JSF render the page selected according to the navigation rules
public String redirectme(String outcome) {
return outcome;
}
37
Pattern 3GWT and Seam navigation rules (6/ 6)> Generate a link or make a browser redirect to a specif ic URL
> GWT client side code for the browser redirection
public static native void redirect(String url)/*-{
$wnd.location = url;
}-*/;
> The call to the redirectme action with the outcome as a parameterredirect("http://www.neoxia.com/GWTSeam/redirectme?outcome=" + outcome);
> Addit ional navigation rules<page view-id="/redirectme" action="#{redirector.redirectme}">
<param name="outcome" value="#{outcome}"/>
</page>
38
Integration Patterns
> GWT client side widget in a JSF page
> GWT as the presentation layer of Seam
> GWT and Seam navigation rules
> GWT in a Seam conversation
> Taking part in a Seam business process
> Seam Security and GWT
39
Pattern 4GWT in a Seam conversation (2/ 5)> Conversational Seam component@Stateful@Name("askQuestion")@Scope(ScopeType.CONVERSATION)public class AskQuestionBean { @PersistenceContext(type=PersistenceContextType.EXTENDED) private EntityManager entityManager;
@In @Out private User user; @Begin public String begin() { (...) } public String ask() { (...) }
public String help() { (...) }
@End public String end() { (...) } @Destroy @Remove public void destroy() {}}
begin endask ask askhelp ask help
entityManager user
40
Pattern 4GWT in a Seam conversation (3/ 5)> We need to get the conversation id and send it to the Seam component on
the server- side
> JavaScript on the client- side .xhtml page to get the conversat ion id<script language="javascript">
var parameters = {
cid: '#{conversation.id}'
};
</script>
> EL expression #{conversation.id} is used to get the current conversation id
41
Pattern 4GWT in a Seam conversation (4/ 5)> GWT client- side : the remote service’s async interface
public interface GWTtoSeamAsync extends RemoteService {
public void askIt(String cid, String question, AsyncCallback callback);
}
> GWT client- side: the widget code
– The widget makes a remote call and sends the conversation id to the Seam remote service
Dictionary parameters = Dictionary.getDictionary("parameters");
String cid = parameters.get("cid");
getService().askIt(cid, text, new AsyncCallback() {...});
42
Pattern 4GWT in a Seam conversation (5/ 5)> Seam server- side: the remote Seam component service
– Service façade: restore the context based on the conversation id and get the service instance in the context
@Name(“com.neoxia.gwtseam.gwt.client.GWTtoSeam")
@Scope(ScopeType.EVENT)
public class GWTtoSeamImpl implements GWTtoSeam {
@In Manager manager;
@WebRemote
public String askIt(String cid, String question) {
// switch to the conversation
manager.switchConversation(cid);
// get the seam component in the conversation cid
MyService myService = (MyService)
Component.getInstance(“com.neoxia.gwtseam.gwt.client.MyService");
// call the action
String answer = myService.askIt(question);
return answer;
}
}
43
Integration Patterns
> GWT client side widget in a JSF page
> GWT as the presentation layer of Seam
> GWT and Seam navigation rules
> GWT in a Seam conversation
> Taking part in a Seam business process
> Seam Security and GWT
44
Pattern 5GWT and Seam Business Processes (1/ 4)
45
Pattern 5GWT and Seam Business Processes (2/ 4)> Seam JBPM annotations
– @CreateProcess
– @ResumeProcess
– @StartTask
– @BeginTask
– @EndTask
– @Transition
> Implicit parameters : taskId and processId– Value of the taskId and processId http request parameters
> taskId and processId http request parameters not sent with GWT AJAX calls
46
Pattern 5GWT and Seam Business Processes (3/ 4)> 1st solut ion: switch to direct jBPM API calls and programmatically get the ids@Stateful
@Name("com.neoxia.intranet.demandeconge.client.DemandeCongeService")
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class DemandeCongeServiceBean implements DemandeCongeService {
@In private Actor actor;
@CreateProcess(definition = "DemandeCongeProcess")
public void createDemandeCongeProcess(DemandeCongeVO demandeConge) {(…)}
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void updateEtatDemandeConge(DemandeCongeVO demandeConge) {
JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
TaskMgmtSession taskMgmtSession = jbpmContext.getTaskMgmtSession();
ProcessInstance processInstance =
jbpmContext.getProcessInstance(demandeConge.getId());
TaskInstance taskInstance =
jbpmContext.getTaskInstanceForUpdate(processInstance.getId());
(…)
47
Pattern 5GWT and Seam Business Processes (4/ 4)> 2nd solution: use GWT’s RequestBuilder class to make direct HTTP calls
– Get the taskId using Seam EL in the page <script language="javascript">
var parameters = { taskid: '#{task.id}‘ };
</script>
– Send the taskid as a method parameter Dictionary parameters = Dictionary.getDictionary("parameters");
String cid = parameters.get(“taskid");
– Construct the HTTP GET request with taskid as a http request parameter String url = "http://www.neoxia.com/GWT/step?taskId="+taskid;
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(url));
builder.setHeader("Content-type", "application/x-www-form-urlencoded");
try {
builder.sendRequest(null, new RequestCallback() { /*(...)*/ });
} catch (RequestException e) {
// Couldn't connect to server
}
48
Integration Patterns
> GWT client side widget in a JSF page
> GWT as the presentation layer of Seam
> GWT and Seam navigation rules
> GWT in a Seam conversation
> Taking part in a Seam business process
> Seam Security and GWT
49
Pattern 6GWT and Seam Security (1/ 3)
> Hide a GWT widget based on Seam security rules
> Adapting remote service behaviour based on user permissions
50
Pattern 6GWT and Seam Security (2/ 3)> Client- side, with JSF
– Hide a GWT widget based on Seam security rules
<rich:panel >
<h:panelGrid columns="2">
<s:div styleClass="info" rendered="#{identity.loggedIn}">
<table align="center">
<tr><td id="slot1"></td><td id="slot2"></td></tr>
</table>
</s:div>
</h:panelGrid>
</rich:panel>
51
Pattern 6GWT and Seam Security (3/ 3)> Server- side:
– Accessing identity, credentials...
– Automatically injected by Seam !
@Name(“com.neoxia.gwtseam.gwt.client.MyService")
public class ServiceImpl implements MyService {
@In Identity identity;
@In Credentials credentials;
52
AGENDA
> Overview
> Introducing Seam
> Introducing GWT
> Why Integrate?
> Integrat ion Patterns
> Conclusion
53
Conclusion
> We can use both GWT and Seam in the same project
– Some features integrate seamlessly
– Other features need more integration effort
– There are st ill few workarounds…
> GWT and Seam are both very active projects
> GWT is now better integrated with Java EE standards
– JDK1.5 support since version 1.5
– War packaging since version 1.6
> Seam is more and more decoupled from JSF and from JBoss AS
– Better GWT integration support since version 2.1.1
54
Questions
Ferda TARTANOGLU http:/ / www.neoxia.com