Integrating Seam and GWT
Integrating 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 consulting 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
>
Int roducing
Seam
>
Int roducing
GWT
>
Why Int egrat e?
>
Int egrat ion Pat t erns
>
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
>
Int roducing
GWT
>
Why Int egrat e?
>
Int egrat ion Pat t erns
>
Conclusion
6
Seam
overview
(1/2)
>
A Java framework
–
For building stateful Web applications
–
With or without J
ava
EE
>
Glue
for integrating several technologies
–
Presentation layer with JSF,
Facelet s,
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
JPA
EJB3
Presentation
Request Controller
Context Management
Business Logic
State Management
JSF
8
AGENDA
>
Overview
>
Int roducing
Seam
>
Introducing
GWT
>
Why Int egrat e?
>
Int egrat ion Pat t erns
>
Conclusion
9
GWT
overview
(1/2)
>
GWT provides mainly a
Java- to- Javascript compiler
–
Code is written 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 writt en in Java as a Servlet
10
GWT model
(2/2)
>
Programming model
–
Java with some restrictions
–
Event- based cont roller
like
Swing
–
Asynchronous RPC for client- server communication
>
Deployment model
–
JavaScript for client- side computing
Host ed on any Web server
Execut ed on the user’s browser
–
Java Servlet for server- side computing
WAR packaging since v 1.6
11
AGENDA
>
Overview
>
Int roducing
Seam
>
Int roducing
GWT
>
Why Integrate?
>
Int egrat ion Pat t erns
>
Conclusion
12
A Case Study
>
An intranet business application with
specific
requirements
–
Interactive U
I
Aj ax !
–
Security
Aut hent ication
Secure communicat ion
Role- based aut horizat ions
–
Workflows
Long- running business processes wit h several participants
–
Messaging
Email
–
Persistence
St orage in MySQL dat abase
–
Transactions
ACID t ransact ions on DB resources
At omicit y and Isolat ion propert ies for mult i- page/act ion int eractive sessions
13
Overlapping Features
of Seam & GWT
>
Rich UI components
–
JavaScript widgets supporting Ajax for GWT
–
JSF components, Richfaces, JSF4Ajax for Seam
>
Support for
server- side comput ing
–
JavaScript remot ing 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
–
Bookmar
k
able pages
–
Support for s
ecurity
–
Templates
15
Integration
Issues
>
GWT
–
O
riented single page stateless applications
–
U
ses a subset of the JDK
>
Seam
–
O
riented multi- page
stateful applications
–
Some features rely on JSF
>
We should try
–
Using the benefits of each technologies
–
Minimizing the
integration effort
16
AGENDA
>
Overview
>
Int roducing
Seam
>
Int roducing
GWT
>
Why Int egrat e?
>
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
1
GWT 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
1
GWT 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
1
GWT 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
1
GWT widget in a JSF page (4/
4
)
>
GWT client- side : The widget
public
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
2
GWT 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 wit h asynchronous requests by
JavaScript (Ajax)
25
Pattern
2
GWT as the presentation layer of Seam (2/6)
>
S
ervice 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
2
GWT 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
2
GWT as the presentation layer of Seam (4/6)
>
GWT
client- side: The w
idget 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
2
GWT 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
2
GWT as the presentation layer of Seam (6/6)
GWT
Seam Remoting
Seam components & contexts
jBPM
JPA
EJB3
Presentation
Request Controller
Context Management
Business Logic
State Management
30
Pattern
1 &
2
GWT remoting + JSF
JSF components + GWT widgets
Seam Remoting
Seam components & contexts
jBPM
JPA
EJB3
Presentation
Request Controller
Context Management
Business Logic
State 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 not ation
–
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
3
GWT 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
3
GWT 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
3
GWT 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
citizenship
–
JSF- independent navigation API that can be used with any presentation
framework
>
Workaround
using 2
subsequent
request
s
–
First request using remoting API
–
Second request through JSF
36
Pattern
3
GWT and Seam navigation rules (5/6)
>
The first met hod called through Seam Remoting
public
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
3
GWT and Seam navigation rules (6/6)
>
G
enerate a link or make a browser redirect to a specific 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 parameter
redirect(
"http://www.neoxia.com/GWTSeam/redirectme?outcome=" + outcome
);
>
Additional n
avigation 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
4
GWT 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
end
ask
ask
ask
help
ask
help
entityManager
user
40
Pattern
4
GWT 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 c
lient - 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
4
GWT in a Seam conversation
(4/5)
>
GWT c
lient- side : the remote service’s async interface
public
interface
GWTtoSeamAsync
extends
RemoteService {
public
void
askIt(
String cid
, String question, AsyncCallback
callback);
}
>
GWT c
lient- 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
4
GWT in a Seam conversation
(5/5)
>
Seam s
erver- 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
5
GWT
and
Seam
Business Processes
(
1
/
4
)
45
Pattern
5
GWT
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
5
GWT
and
Seam
Business Processes
(
3
/
4
)
>
1
st
solut ion: swit ch to direct j BPM 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
5
GWT
and
Seam
Business Processes
(
4
/
4
)
>
2
nd
solution: use GWT’s RequestBuilder class to make direct HTTP calls
–
Get t he t askId using Seam EL in t he page
<
script
language
=
"javascript"
>
var
parameters = { taskid: '#{task.id}‘ };
</
script
>
–
Send t he taskid as a met hod paramet er
Dictionary parameters
=
Dictionary.
getDictionary
(
"parameters"
);
String cid = parameters.get(
“
task
id"
);
–
Construct the HTTP GET request wit h t askid as a
ht t p request
paramet er
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
6
GWT
and
Seam
Security
(
1
/3)
>
Hide a GWT widget based on Seam security rules
>
Adapting remote service behaviour based on user permissions
50
Pattern
6
GWT
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
6
GWT
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
>
Int roducing
Seam
>
Int roducing
GWT
>
Why Int egrat e?
>
Int egrat ion Pat t erns
>
Conclusion
53
Conclusion
>
We can use both GWT and Seam in the same project
–
Some features int egrate seamlessly
–
Other features need more integration effort
–
There are still few workarounds…
>
GWT and Seam are both very active projects
>
GWT is
now
better integrated with J
ava
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
ht tp://www.neoxia.com
NEOXIA
ferda.t art anoglu@neoxia.com
Enter the password to open this PDF file:
File name:
-
File size:
-
Title:
-
Author:
-
Subject:
-
Keywords:
-
Creation Date:
-
Modification Date:
-
Creator:
-
PDF Producer:
-
PDF Version:
-
Page Count:
-
Preparing document for printing…
0%
Σχόλια 0
Συνδεθείτε για να κοινοποιήσετε σχόλιο