Professional Documents
Culture Documents
Lessons Learned
Dipl. Wi.-Ing. Papick Garcia Taboada
…js
…html
…css
!
none of it
!
…jcp
…oracle
… IBM
… backend
what is a GWT
application?
a chunk of JS that does a lot of DOM
manipulation to create web
applications
UI component model Components
RootPanel.get().add(t);
Browser Composite
+ testability!
+ maintainance!
+ product development
Architecture shift
Web applications
user action
s p o n s e
ful l html re
user action
s p o n s e
full html re
user action
s p o n s e
ful l html re
e b n t
w e
I A pm
R lo
v e Browser Server
d e
first reques
t
e s p o n s e
full html r
event
event
data reque
st
event
data
event
data reque
st
data
Web frameworks
low level, generic tools
let‘s build big things
TextBox t0 = new TextBox();
TextBox t1 = new TextBox();
TextBox t2 = new TextBox();
TextBox t3 = new TextBox();
TextBox t4 = new TextBox();
VerticalPanel...
SplitPanel...
ScrollPanel
RootPanel.get().add(mainPanel);
maintainance hell
MacGyver
All he needed was a ballpoint
pen and a paper clip
Ops
Widget t = new TextBox();
!
RootPanel.get().add(t);
not enough…
app-framework wizardry needed
‣ GWT Development
‣ Basics
‣ Structuring the UI
‣ Talking to the server
GWT DEVELOPMENT IS COMPLICATED
HOT NEW STUFF.
NOT REALLY
is not new,
GWT development but different
WHY?
1) WEB DEVELOPMENT
IS NOT NEW...
HTML 2.0 HTML 4.0 update
November 1995 April 1998
USE MVP!
You will get PRESENTER
used to it
VIEW
MODEL
USE MVP!
MOCK VIEW
MODEL
USE MVP!
You will get PRESENTER
used to it
DESKTOP VIEW
MOBILE VIEW
event bus please
http://jarrettws.blogspot.de/2010/05/public-transport.html
eventbus.fireEvent(
NotificationEvent.info(
"Daten wurden erfolgreich gespeichert"
)
);
SINGLETON
don‘t public static instance
BUT ON IE 6 IT IS SO SLOW!
BUT ON IE 7 IT IS SO SLOW!
BUT ON IE 8 IT IS SO SLOW!
BUT ON IE 9 IT IS SO SLOW!
DID ANYONE TEST ON IE / SURFACE?
MOBILE?
DID ANYONE TEST ON IE / SURFACE?
MOBILE?
DID ANYONE TEST ON IE / SURFACE?
CHEAP ANDROID DEVICES?
browsers day to day job
too many HTTP requests
> 2400 DOM elements
Awesome?
too many widgets
use large HTML chunks
use large HTML chunks
too many widgets ain‘t good
WHY?
<div />
in GWT a Widget is a JS thing
holding a DOM thing
CREATE CUSTOM WIDGETS
CREATE CUSTOM EVENTS
extend composite!!!
@-webkit-keyframes redPulse
{
from
{
box-shadow: 0px 0px 2px #ff0033;
}
50%
{
box-shadow: 0px 0px 10px #ff0033;
}
to
{
box-shadow: 0px 0px 2px #ff0033;
}
}
use LayoutPanel
‣ GWT Development
‣ Basics
‣ Structuring the UI
‣ Talking to the server
SINGLE PAGE APPLICATION
NAVIGATION?
some action
?
mainPanel.setWiget( bWidget );
mainPanel.setWiget( aWidget );
„View B“
„View A“
„View A“
„View D“
hard to maintain
history
management
from day one!
!
CUSTOM
events
datepicker
sends WEEK
selected event
BOOKMARKABLE
!
pin POPUPS to
one side of the
window
Search DIALOG Don‘t move your user
slides in from right away from his „PLACE“
side, stays on TOP unless you have to.
Navigation should not hurt
• The application shown uses only 3
levels of navigation,
DOES NOT NEED MORE
• PLACES used for bookmarkable
entry points/ back button
navigation consistency
• Activities should be STATELESS, to
survive page reloads
• Learn from OTHERS, lookout for
hashtags…
Once upon a time,
a young good designer did a good looking design...
Interface
Versioning is
a monstrous
thing
this will be an object
TYPESAFETY,
!
AND INTERFACES
now we just have one
interface with one method
command
pattern
GOF Pattern
!
commonly used in
Rich Clients
!
someAction
EXECUTE someActionHandler
someResult
someAction
POJOS someActionHandler
someResult
client server
GWT client
someAction
GWT-RPC
someActionHandler
someResult
batching
caching
caching
exception translation
security security
client server
Java client
someAction
RMI / HTTPInvoker
someActionHandler
someResult
batching
caching
caching
exception translation
security security
client server
Mobile client
someAction
JSON-servlet
someActionHandler
someResult
batching
caching
caching
exception translation
security security
type safety aka DTOs
Reusable
Action Result
<A extends Action<R>, R extends Result>
void execute(A action, AsyncCallback<R> callback)
dispatch.execute(
!
new TerminLoadAction(terminId),
new AsyncCallback<DataResult<TerminData>>() {
!
@Override
public void onFailure(Throwable caught) {
}
!
@Override
public void onSuccess(DataResult<TerminData> result) {
}
!
}
!
);
Server side
type safety
again
handler to action
mapping public interface ActionHandler
<A extends Action<R>, R extends Result> {
!
Class<A> getActionType();
!
!
!
!
R execute(
action execution A action, Execution context for server side
ExecutionContext context)
command execution
throws DispatchException;
!
}
declared
exception
hiearchy
Server side
@ActionHandlerBean
custom annotationspring @Transactional
public final class TerminDataLoadHandler
implements ActionHandler<TerminLoadAction, DataResult<TerminData>> {
!
@Autowired
access to backend !
private TerminDAO terminDao;
@Override
public DataResult<TerminData> execute(
TerminLoadAction action,
ExecutionContext context) throws DispatchException {
!
TerminBean termin = …
!
TerminData data = …
!
business logic,
type safe result !
return new DataResult<TerminData>(data);
} etc…
!
@Override
public Class<TerminLoadAction> getActionType() {
return TerminLoadAction.class;
}
!
}
interface
versioning
hell?
easy way right way?
POJOS someActionHandler
someResult
different versions can coexist!
someAction
someActionV2
multiple
someActionHandler
versions
someActionHandlerV2
someResult
same result
someAction
someActionV2
multiple
someActionHandler
versions
someActionHandlerV2
someResult
someResultV2
different results
why batch?
do it
then do this
finally do that
done
do it, then this, finally that
done
solving common
• one batch call is better than 10
single calls
problems
• less data
• less roundtrip latency
• avoid connection bottleneck
• ensure server side execution
order
• less roundtrips
someAction1
client server
someAction2
batchActionHandler
someAction3
someAction1
batchAction
someAction2
batchResult
someResult1 someAction3
someResult2
Scheduler.scheduleEntry(…)
Scheduler.scheduleFinally(…)
Scheduler.scheduleDeferred(…)
IDLE
Scheduler.scheduleEntry(…)
Scheduler.scheduleFinally(…)
IDLE
Scheduler.scheduleEntry(…)
collect commands
cmd 1!
cmd 2!
GWT code execution cmd 3!
cmd …
+
!
reloadDashboardTermine DataListResult<Termin>
toggleTerminMetadata BooleanResult
reloadTermin DataResult<Termin>
toggleTerminMetadata BooleanResult
loadMonthStats DataResult<MonthStats>
loadMonthTermine DataListResult<Termin>
+ caching
+ reauth when session expired
+ exception handling
Thanks!
‣ GWT Development
‣ Basics
‣ Structuring the UI
‣ Talking to the server
http://j.mp/g w t - j a v a l a n d - 2 0 1 4