Tải bản đầy đủ (.pdf) (480 trang)

Apress pro web 2 0 application development with GWT may 2008 ISBN 1590599853 pdf

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (5.47 MB, 480 trang )

 CYAN
 MAGENTA

 YELLOW
  BLACK
 PANTONE 123 C

Books for professionals by professionals ®

The EXPERT’s VOIce ® in Web Development
Companion
eBook Available

Pro Web 2.0 Application
Development with GWT

Pro

This book is for developers who are ready to move beyond small proof-of-concept
sample applications and want to look at the issues surrounding a real deployment of GWT. If you want to see what the guts of a full-fledged GWT application
look like, this is the book for you.
GWT 1.5 is a game-changing technology, but it doesn’t exist in a bubble. Real
deployments need to connect to your database, enforce authentication, protect
against security threats, and allow good search engine optimization.
To show you all this, we’ll look at the code behind a real, live web site called
ToCollege.net. This application specializes in helping students who are applying
to colleges; it allows them to manage their application processes and compare
the rankings that they give to schools. It’s a slick application that’s ready for you
to sign up for and use.
This book will give you a walking tour of this modern Web 2.0 start-up’s codebase. The included source code will provide a functional demonstration of how
to merge together the modern Java stack including Hibernate, Spring Security,


Spring MVC 2.5, SiteMesh, and FreeMarker. This fully functioning application is
better than treasure if you’re a developer trying to wire GWT into a Maven build
environment who just wants to see some code that makes it work. If a full tour of
15,000 lines of source code that includes everything from Google Gears integration
to Acegi Security, OpenID, Lucene full-text searching, and Google Maps sounds
like a good thing, I think you’ll enjoy this book.
Yours,
Jeff Dwyer
Companion eBook

Related Titles

See last page for details
on $10 eBook version



www.apress.com



ISBN-13: 978-1-59059-985-3
ISBN-10: 1-59059-985-3
54499

US $44.99

Dwyer

SOURCE CODE ONLINE


Web 2.0 Application Development with GWT

Dear Reader,

Covers

Pro

GWT 1.5

Web
2.0
Application Development
with GWT
Learn real-world, professional GWT techniques by
following an in-depth case study of a Web 2.0 site.

Jeff Dwyer

Shelve in
Web Development
User level:
Intermediate–Advanced

9 781590 599853

this print for content only—size & color not accurate

spine = 0.909" 480 page count




9853FM.qxd

4/15/08

11:14 AM

Page i

Pro Web 2.0 Application
Development with GWT

Jeff Dwyer


9853FM.qxd

4/15/08

11:14 AM

Page ii

Pro Web 2.0 Application Development with GWT
Copyright © 2008 by Jeff Dwyer
All rights reserved. No part of this work may be reproduced or transmitted in any form or by any means,
electronic or mechanical, including photocopying, recording, or by any information storage or retrieval
system, without the prior written permission of the copyright owner and the publisher.

ISBN-13 (pbk): 978-1-59059-985-3
ISBN-10 (pbk): 1-59059-985-3
ISBN-13 (electronic): 978-1-4302-0638-5
ISBN-10 (electronic): 1-4302-0638-1
Printed and bound in the United States of America 9 8 7 6 5 4 3 2 1
Trademarked names may appear in this book. Rather than use a trademark symbol with every occurrence
of a trademarked name, we use the names only in an editorial fashion and to the benefit of the trademark
owner, with no intention of infringement of the trademark.
Java™ and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc., in
the US and other countries. Apress, Inc., is not affiliated with Sun Microsystems, Inc., and this book was
written without endorsement from Sun Microsystems, Inc.
Lead Editors: Steve Anglin, Ben Renow-Clarke
Technical Reviewer: Massimo Nardone
Editorial Board: Clay Andres, Steve Anglin, Ewan Buckingham, Tony Campbell, Gary Cornell,
Jonathan Gennick, Matthew Moodie, Joseph Ottinger, Jeffrey Pepper, Frank Pohlmann,
Ben Renow-Clarke, Dominic Shakeshaft, Matt Wade, Tom Welsh
Project Manager: Kylie Johnston
Copy Editor: Heather Lang
Associate Production Director: Kari Brooks-Copony
Production Editor: Liz Berry
Compositor: Dina Quan
Proofreader: Linda Marousek
Indexer: Carol Burbo
Artist: April Milne
Cover Designer: Kurt Krames
Manufacturing Director: Tom Debolski
Distributed to the book trade worldwide by Springer-Verlag New York, Inc., 233 Spring Street, 6th Floor,
New York, NY 10013. Phone 1-800-SPRINGER, fax 201-348-4505, e-mail , or
visit .
For information on translations, please contact Apress directly at 2855 Telegraph Avenue, Suite 600,

Berkeley, CA 94705. Phone 510-549-5930, fax 510-549-5939, e-mail , or visit
.
Apress and friends of ED books may be purchased in bulk for academic, corporate, or promotional use.
eBook versions and licenses are also available for most titles. For more information, reference our Special
Bulk Sales–eBook Licensing web page at />The information in this book is distributed on an “as is” basis, without warranty. Although every precaution has been taken in the preparation of this work, neither the author(s) nor Apress shall have any
liability to any person or entity with respect to any loss or damage caused or alleged to be caused directly
or indirectly by the information contained in this work.
The source code for this book is available to readers at .


9853FM.qxd

4/15/08

11:14 AM

Page iii

To those who help me realize it’s easier than we think


9853FM.qxd

4/15/08

11:14 AM

Page iv



9853FM.qxd

4/15/08

11:14 AM

Page v

Contents at a Glance
About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
About the Technical Reviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii

PART 1

■■■

■CHAPTER 1
■CHAPTER 2

PART 2

Why GWT? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

■■■

■CHAPTER 3
■CHAPTER 4

■CHAPTER 5
■CHAPTER 6
■CHAPTER 7
■CHAPTER 8
■CHAPTER 9
■CHAPTER 10
■CHAPTER 11
■CHAPTER 12
■CHAPTER 13
■APPENDIX

What Can GWT Do for You?

ToCollege.net

Designing ToCollege.net . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
GWT and Spring MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Securing Our Site . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Saving Our Work. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
ToCollege.net’s GWT GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
Google Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
Suggest Boxes and Full Text Search . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
Forums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
Security and Authorization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
Search Engine Optimization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
Google Gears . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
Building ToCollege.net . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391

■INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427


v


9853FM.qxd

4/15/08

11:14 AM

Page vi


9853FM.qxd

4/15/08

11:14 AM

Page vii

Contents
About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
About the Technical Reviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii

PART 1

■■■


■CHAPTER 1

What Can GWT Do for You?

Why GWT? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
“May You Live in Interesting Times” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
To HTML or Not to HTML? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
So What Is GWT? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
But JavaScript Is Better Than Java! . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Speed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Tools, Tools, Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
JavaScript Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Community . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
The Rest of the Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Maven 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

■CHAPTER 2

Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Sample Project Goals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
GWT Project Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Public . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
The GWT Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

vii



9853FM.qxd

viii

4/15/08

11:14 AM

Page viii

■CONTENTS

Sample Calculator Project Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
NumberButton.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
ControlButton.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Calculator.java (1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
ControlAction.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Calculator.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
The EntryPoint Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
CalcButton: A CSS Enhancement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Code Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
The Advantages of Compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Pure Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

PART 2

■■■


■CHAPTER 3

ToCollege.net

Designing ToCollege.net . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
User Stories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
User Story 1: Adding a School . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
User Story 2: Adding Opinions of Schools . . . . . . . . . . . . . . . . . . . . . . 48
User Story 3: Sorting Schools into Tiers . . . . . . . . . . . . . . . . . . . . . . . 48
User Story 4: Viewing Schools on a Map . . . . . . . . . . . . . . . . . . . . . . . 48
User Story 5: Deciding Among Schools . . . . . . . . . . . . . . . . . . . . . . . . 49
User Story 6: Managing the Application Process . . . . . . . . . . . . . . . . 49
What’s Next. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Overview of ToCollege.net . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
My Rankings List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
My Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
My Decision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
College Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Forums. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54


9853FM.qxd

4/15/08

11:14 AM

Page ix


■CONTENTS

The College.net Domain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Using Abstract Property POJOs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
User and School Objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Application Process Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
The Process Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Revisiting the User’s List of Schools with a Sorted Map . . . . . . . . . . 58
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

■CHAPTER 4

GWT and Spring MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Integrating with a Web Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Why Use Both? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Choosing Spring MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Templating with FreeMarker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
The Spring MVC Site . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Splash! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
A Quick FreeMarker Tutorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
The Dispatcher Servlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Using a Mock for Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
REST-Style URLs in CollegeController.java . . . . . . . . . . . . . . . . . . . . . 86
Basic GWT Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Putting the Calculator in Spring MVC . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Modules, Entry Points, and Dictionaries . . . . . . . . . . . . . . . . . . . . . . . 91
One Module per Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
One Module to Rule Them All . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Passing Information with JavaScript Dictionaries . . . . . . . . . . . . . . . 92
Showing a Loading Message . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

ToCollege.Net RPC Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
ToCollegeApp.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Dispatcher Servlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
ApplicationContext.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
GWTController.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Serialization Policy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
MyPage.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

ix


9853FM.qxd

x

4/15/08

11:14 AM

Page x

■CONTENTS

■CHAPTER 5

Securing Our Site . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Acegi Security System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
Acegi Security Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Acegi Security and Our Domain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

Implementing Acegi Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Add a Servlet Filter to web.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Creating the Acegi Security Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Creating a Login Page in Spring MVC. . . . . . . . . . . . . . . . . . . . . . . . . 121
Getting the Authenticated User in Code . . . . . . . . . . . . . . . . . . . . . . . 123
OpenID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Acegi Security OpenID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
OpenIDLoginController . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
OpenID Bean Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Updating UserDAO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
Integrating GWT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
Getting the Current User . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
Logging In from GWT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Login Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136

■CHAPTER 6

Saving Our Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Adding a Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
DAOs and the ToCollege.net Architecture . . . . . . . . . . . . . . . . . . . . . 140
GWT-Specific Persistence Concerns . . . . . . . . . . . . . . . . . . . . . . . . . 141
The Command Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
Building the DAO Layer. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
Integrating Hibernate. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
Mapping the User Class with User.hbm.xml . . . . . . . . . . . . . . . . . . . 148
Application.java and Application.hbm.xml . . . . . . . . . . . . . . . . . . . . . 154
SchoolDAO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
Hibernate and GWT: No DTOs Necessary . . . . . . . . . . . . . . . . . . . . . . . . . . 157
The Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

Possible Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
Filter and Go . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
Attaching HibernateFilter to GWT Serialization . . . . . . . . . . . . . . . . . 162


9853FM.qxd

4/15/08

11:14 AM

Page xi

■CONTENTS

The Command Pattern, a Powerful Ally . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
What Is the Command Pattern?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
How the Command Pattern Works . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Implementing Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
Testing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Testing the DAO Layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
Testing the Service Layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179

■CHAPTER 7

ToCollege.net’s GWT GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
Basic My Page GUI Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
Tab Listeners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
History Management: Repairing the Back Button . . . . . . . . . . . . . . 185

Functional History and Bookmarking . . . . . . . . . . . . . . . . . . . . . . . . . 187
RPC Status Notification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Step 1: Adding a <div> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Step 2: Creating a StatusPanel on Bootstrap . . . . . . . . . . . . . . . . . . 190
Step 3: Implement the RPC Notification Strategy
(StdAsyncCallback) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Step 4: Displaying the Status with StatusPanel . . . . . . . . . . . . . . . . 193
Step 5: Making It Cool with Fading . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
Drag ’n’ Drop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
DropController and DragController . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
Making Widgets Draggable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
DragHandler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
RichTextArea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
RichTextToolbar’s ImageBundle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
VerticalLabel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212

■CHAPTER 8

Google Maps

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213

The Mashup Landscape . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
Where We’ll Use Maps in ToCollege.net . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
The Google Maps API and Key . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216

xi



9853FM.qxd

xii

4/15/08

11:14 AM

Page xii

■CONTENTS

Using the GWT Google APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Adding to Maven . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Module Inheritance and Maps JavaScript . . . . . . . . . . . . . . . . . . . . . 218
Geocoding Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
A Simple Bulk Geocoder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
Updating the My List College Map Tab . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
Creating Another Tab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
Creating a Map Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
Loading Schools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
Making Clickable Markers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
Why the Dialog Box? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
Reusable Map Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
Integrating with Spring MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
The GWT Side of CollegeMap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235

■CHAPTER 9


Suggest Boxes and Full Text Search

. . . . . . . . . . . . . . . . . . . . . 237

A Basic Suggest Box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
An Ideal Remote Suggest Box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
Implementing SchoolCompleter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
Server-Side Suggestion Matching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
Performance Concerns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
A Basic, SQL LIKE Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
Full Text Search Engines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264

■CHAPTER 10 Forums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
Designing Forums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
List of Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
Post Display List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
Reply / Create New Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
History Management and Bookmarkable URLs . . . . . . . . . . . . . . . . 269


9853FM.qxd

4/15/08

11:14 AM

Page xiii

■CONTENTS


Implementing Forums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
Data Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
Forum Page Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
Extras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305

■CHAPTER 11 Security and Authorization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
Authorization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
Protecting Our Domain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Remembering Security with Our Guilty Consciences . . . . . . . . . . . 310
Selects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
Alternative Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
GWT Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
Cross-Site Scripting (XSS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
A Sample XSS Attack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
GWT’s Inherent Protection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
Analyzing XSS in RichTextArea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
Analyzing XSS in FreeMarker. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
Analyzing XSS in Spring MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
Securing Ourselves from XSS with Filters . . . . . . . . . . . . . . . . . . . . . 317
Cross-Site Forged Requests (XSRF) . . . . . . . . . . . . . . . . . . . . . . . . . . 323
Final Security Concerns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
Data Manipulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
Out of Order Requests. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
SQL Injections. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332

■CHAPTER 12 Search Engine Optimization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
How Search Works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333

Crawling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
Indexing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
Serving. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
Search Engine Optimization (SEO) . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
AJAX and Searching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
GWT and Searching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336

xiii


9853FM.qxd

xiv

4/15/08

11:14 AM

Page xiv

■CONTENTS

Optimizing ToCollege.net for Indexing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
Be the Bot: Visualizing Your Site Like a Bot Does . . . . . . . . . . . . . . 338
Option 1: Secondary Site . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
Option 2: User Agent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
Option 3: Hidden <div> and <noscript> Elements . . . . . . . . . . . . . 340
Implementing Bootstrapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
Updated Freemarker <@gwt.widget> . . . . . . . . . . . . . . . . . . . . . . . . 341
Reusing Serialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344

Bootstrapping Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
GWT Startup with Bootstrapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
The Proof in the Pudding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
Optimizing the Crawling of ToCollege.net . . . . . . . . . . . . . . . . . . . . . . . . . 350
Robots.txt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355

■CHAPTER 13 Google Gears . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
Limitations of AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
Always Needs an Internet Connection . . . . . . . . . . . . . . . . . . . . . . . . 357
Single Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
No Good Storage Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
Introducing Gears . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
Support for Google Gears . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
Service-Oriented Front-End Architecture. . . . . . . . . . . . . . . . . . . . . . 360
LocalServer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
Manifest Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
The Difficulties of Manifests and a New Hope . . . . . . . . . . . . . . . . . 368
WorkerPool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
A GWT Workaround . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
Gears Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372
Creating a Simple Database. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373
Gears Database Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
ToCollege.net . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376


9853FM.qxd

4/15/08


11:14 AM

Page xv

■CONTENTS

Caching SuggestBoxes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
Saving Objects to Gears . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
Service Cache. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
Google Gears Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
dbquery.html . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
webcachetool.html . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387
What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388

■APPENDIX

Building ToCollege.net . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
General Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
Eclipse Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
Cygwin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394
Maven . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394
The ToCollege.net Codebase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
Check Out the Source Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
Compiling with Maven . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401
Install-All . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
Running mvn compile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
Installing GWT. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406
Manually Installing JARs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411

Run the Sample Calculator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
Set Up the Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413
Environment Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
Running ToCollege.net . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
Initialize the Search Engine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
Mac-Specific Launch Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . 423
Developing with ToCollege.net . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423
Creating a WAR file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424
Integrating Maven and GWT Compilation . . . . . . . . . . . . . . . . . . . . . 424
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426

■INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427

xv


9853FM.qxd

4/15/08

11:14 AM

Page xvi


9853FM.qxd

4/15/08

11:14 AM


Page xvii

About the Author
■JEFF DWYER is a developer and entrepreneur who is the founder of
ToCollege.net and MyHippocampus.com. His background is in medical software, where he has published research on aneurysm stress
and endovascular repair and has patented techniques in anatomical
visualization. He currently works at PatientsLikeMe. As a developer,
Jeff likes nothing better than to leverage high-quality, open source
code so he can focus on getting results. He believes that GWT has
fundamentally altered the feasibility of large Web 2.0 applications.
Jeff is a graduate of Dartmouth College and lives in Vermont, where he enjoys skiing,
rowing, and interminably long winters.

xvii


9853FM.qxd

4/15/08

11:14 AM

Page xviii


9853FM.qxd

4/15/08


11:14 AM

Page xix

About the Technical Reviewer
■MASSIMO NARDONE was born under Mount Vesuvius. He holds a
master of science degree in computing science from the University of
Salerno, Italy. He currently works as an IT security and infrastructure
architect, a security consultant, and the Finnish Invention Development Team Leader (FIDTL) for IBM Finland. His responsibilities
include IT infrastructure, security auditing and assessment, PKI/WPKI,
secure tunneling, LDAP security, and SmartCard security.
With more than 13 years of work experience in the mobile, security, and WWW technology areas for both national and international projects, he has worked as a project
manager, software engineer, research engineer, chief security architect, and software
specialist. He also worked as a visiting lecturer and supervisor for exercises at the Networking Laboratory of the Helsinki University of Technology (TKK) for the Security of
Communication Protocols course.
Massimo is very familiar with security communication protocols testing tools and
methodologies and has been developing Internet and mobile applications involving different technologies using many programming languages. He also works as a security
application auditing expert to check on new application vulnerabilities utilizing security
standards like ISO 17799 and ISO 27001 (formerly BS7799:2).
He has researched, designed, and implemented security methodologies for different
areas like Standard BS7799, PKI and WPKI, Security Java (JAAS, JSSE, JCE, etc.), BEA
Web Logic Security, J2EE Security, LDAP Security, SSO, Apache Security, MS SQL Server
Security, XML Security, and SmartCard Security.
Massimo has served as a technical reviewer for many different IT book publishers in
areas like security, WWW technology, and databases.
He currently holds four international patents (PKI, SIP, SAML, and proxy areas).

xix



9853FM.qxd

4/15/08

11:14 AM

Page xx


9853FM.qxd

4/15/08

11:14 AM

Page xxi

Acknowledgments
I

’d like to thank everyone at Apress who made this book possible. Kylie Johnston, you
deserve a medal for keeping this book on track despite my best efforts to the contrary.
Heather Lang, your grammatical psychiatry was much appreciated. I have a long way to
go before attributive nouns and I see eye to eye, but I think we made big strides. Thanks
also to Steve Anglin, Ben Renow-Clarke, Stephanie Parker, and Tina Nielsen. I’ve enjoyed
working with you all. Finally, thanks to the technical reviewer, Massimo Nardone, known
only as IBM_USER throughout the project. Though your identity was a mystery, your
feedback was first rate.
Thanks to Sumit Chandel and Pamela Fox for your Herculean efforts to ensure that I
was not sued as a result of this book. I shall recommend that you receive the Order of the

Red Tape Cutters. Thanks to everyone at the Google Web Toolkit conference. From GWT
team members to presenters to attendees, you all helped hone the message that I’ve tried
to get across in this book.
To all of the various nontechnical people I know, merci beaucoup—and thank you for
feigning interest! Thanks to my dear mother as well, who has had to put up with more of
this than anyone should really have to. And to every one of the Hamlet Project members,
truly, you keep me sane. If there are more than three people, they might just think it’s a
revolution. J3PO, this is just the start.
Finally, a large mwah to Brenda: I’m very much enjoying our recipe for success.

xxi


9853FM.qxd

4/15/08

11:14 AM

Page xxii


9853FM.qxd

4/15/08

11:14 AM

Page xxiii


Introduction
W

hen I quit my day job in the summer of 2006 to bring an idea of mine to life as an
Internet startup, I was faced with a huge number of questions and not a lot of clear
answers. The excitement of starting a new project was soon tempered by the difficulty of
choosing among the dizzying array of possible technical platforms and solutions. While
the shelves were full of books focusing on each of the components of a web application,
what I really wanted was a look at how all the pieces fit together.
Too often, I found books that seemed like annotated versions of Javadocs, with helpful explanatory notes that setEnabled(boolean enabled) would set the enabled flag. At the
other end of the spectrum were abstract architectural tracts that might have made for
good reading but certainly didn’t give me a head start on the architecture. I wanted to see
how these technologies worked when used for nontrivial applications; I wanted to see
ugly problems and their solutions—I wanted a look at the source code of a modern web
application.
For those of us who learned HTML and JavaScript by using the View Source option,
there’s nothing like getting your hands on working source code. So I had an idea: what if
I created a company, a real, functional company, with a modern web site and then gave
you the keys to the castle to go poke around? That’s the goal of this book, to give you the
tour of a cool, state of the art Web 2.0 application.
The main content of this book focuses on developing one big site with the Google
Web Toolkit (GWT). In the summer of 2006, GWT 1.0.21 had been freshly released, and I
had the good fortune to give it a test drive. It turned out to be a fortuitous choice. Working in an unfunded start-up shines a powerful spotlight on the relationship between
writing code and getting results. The only thing worse than struggling for hours to get
your site to work in different browsers is not getting paid for those hours! Programming
with GWT meant I didn’t need to get a master’s degree in browser compatibilities and
that I could refactor my code quickly and easily as my ideas changed. Most importantly,
programming in GWT was fun.
There’s a lot of material in this book that isn’t purely related to GWT, which, in my
mind, is a good thing. I could’ve cropped out some of this information to make things

more focused, but it seems to me that this interplay between things is precisely what
takes the most time to figure out on your own, and that discussing this interplay is the
area in which this book can be most valuable. Walking through online tutorials is usually
enough to get your head around one technology, but getting all the elements to play
nicely together is where the rubber hits the road.
xxiii


×