SlideShare ist ein Scribd-Unternehmen logo
1 von 69
Downloaden Sie, um offline zu lesen
#javaedge2012

GWT Enterprise Edition
By: Gilad Garon

March 2012
Agenda
Overview:

» Vanilla GWT
» Improved RPC
» Enhanced Request Factory
» Request Builder
» Tying it all together
VANILLA GWT SERVER SIDE
Vanilla GWT Server Side
The Lowdown on GWT RMI:
» Communication is always asynchronous
» Client side code is Java translated to JavaScript
» Server side code is based on GWT Servlets
Vanilla GWT Server Side
Three Flavors of RMI:
» GWT RPC

»
»

 Service oriented
RequestFactory
 Data oriented
RequestBuilder
 Manual HTTP Requests
Vanilla GWT RMI
GWT server side application:
RemoteServiceServlet

RequestFactoryServlet

HttpServlet

GWT Application WAR

HTTP (Async)
Vanilla GWT Server Side
Use case examples:

» GWT RPC

»
»

 Standalone services: Authentication
RequestFactory
 Data services: Domain entity CRUD operations
RequestBuilder
 Cross site integration: Reading data from a remote
server
IMPROVED RPC
Vanilla RPC
GWT-RPC in a nutshell:

» Each service is a standalone RPC Servlet
» Client invokes a generated interface
» Transports concrete java objects
Vanilla RPC
How can we improve it?

» Use the command pattern
 Use a single RPC Servlet for all of your services

» Integrate with an IoC container
 Wire all of your services easily

» Don’t use interfaces, use only concrete classes
Command Pattern
Meet the Command Pattern:

» A Single RPC Servlet for all of your services
» Action class represents the client request
» Result class represents the server response
» ActionHandler class handles the Action and
returns the Result
Command Pattern
Architecture
Dispatcher RPC Servlet

Client Browser

Action Handler

Action

Dispatch Service

Action

Result

Async Dispatcher

Action Result
Command Pattern
Benefits:
» Server side:
 Single RPC Servlet for all services

» Client side:





Caching
Batching
Centralized failure handling
Undo / Redo support

Don’t reinvent the wheel, use existing frameworks:
 GWTP
 GWT-Dispatch
Command Pattern, Example
Action:
public class GetDocumentByIDAction extends Action<GetDocumentByIDResult> {
private String id;
public String getId() {
return id;
}
}

Result:
public class GetDocumentByIDResult implements Result {
private String documentContents;
public String getDocument() {
return documentContents;
}
}
Command Pattern
ActionHandler:
public class GetDocummentByIDActionHandler implements
ActionHandler<GetDocummentByIDAction, GetDocummentByIDResult> {
DocumentService documentService;
@Override
public GetDocummentByIDResult execute(GetDocummentByIDAction action) {
String doc = documentService.getDocumentById(action.getId());
return new GetDocummentByIDResult (doc);
}
}
IoC / DI
Integrate with an IoC container:
» Central point for configuration:

»
»

 Services
 DAO
Minimizes the amount of code in your application
 Inject what you need
Make your application more testable
 Easy way to create mockup objects
Spring Integration
Simple Spring example:
public class MyRPCServiceImpl extends RemoteServiceServlet implements MyRPCService {
private ApplicationContext applicationContext;

@Override
public void init() {
super.init()
ApplicationContext context =
WebApplicationContextUtils.getWebApplicationContext (getServletContext());
}
@Override
public String doSomething() {
return applicationContext.getBean(SpringRPCService.class).doSomething();
}

}
Guice Integration
Guiceified Servlet:
public class MyRPCImpl extends RemoteServiceServlet implements MyRPC {
private final SomeService service;
public MyRPCImpl(){
this.service = MyGuiceFactory.getInjector().getInstance(SomeService.class);
}

@Override
public String doSomething() {
return service.doSomething();
}
}
Summary
So far we’ve seen:

» Command pattern
 Reduces number of RPC servlets
 Allows for smart RMI
» IoC Integration
 Enables single bootstrap
 Allows Dependency Injection
DIY RPC:
What else can we do?
Replace the entire RPC mechanism:
» GWT offers static methods to process RPC
» We can use it to create our own RPC Servlets
implementations
DIY RPC:
HttpServlet.doPost()

HttpServletRequest request

RPCServletUtils.
readContentAsGwtRpc(request)
String payload

Invoke Method by reflection using:
•
•

rpcRequest.getMethod()
rpcRequest.getParameters()

RPCRequest request

RPC.decodeRequest(p
ayload,…)

Object result

RPC.encodeResponseForSuccess
(rpcRequest.getMethod(), result,
serializationPolicy, serializationFlags);

String payload

RPCServletUtils.writeResponse
(getServletContext(), response,
payload, gzipEncode)
IMPROVED REQUEST FACTORY
Request Factory
RequestFactory in a nutshell:
» Designed for Data oriented services
» Lightweight
» Integrates with any ORM framework
Request Factory
Created for data oriented services:
» Uses proxies as Data Transfer objects
» Uses JSON as a transport layer
» Transfers shallow object graph
» Tracks your domain objects, transfers only delta
changes
» Loosely coupled with your sever side
Request Factory
The main players:
Domain definition

RequestFactory equivalent

Entity

EntityProxy

POJO

ValueProxy

Service definitions

RequestContext

Service implementations

N/A
Request Factory
Other players:
» Entity Locators
▪ A way to track domain entities
» Service Locators
▪ A way to instantiate domain services
Request Factory
Entity mappings:
JPA Entity:

Entity Proxy:

@Entity
public class Person {
@Id
private Long id;
private Integer version;
private String firstName
private String lastName

@ProxyFor(value=Person.class, locator=MyLocator.class)
public interface PersonProxy extends EntityProxy {
Long getId();
Integer getVersion();
String getFirstName();
String getLastName();

@Embedded
private Address address;
...

}

//ValueProxy
AddressProxy getAddress();
...

}
Request Factory
RequestContext:
@Service(value=PersonDAO.class,locator = MyServiceLocator.class)
public interface PersonRequest extends RequestContext {
Request<Void> saveOrUpdate(PersonProxy person);
Request<List<PersonProxy>> findAllPersons();
Request<PersonProxy> findPerson(Long id);
}

Our actual service:
public class PersonDAO {
public void saveOrUpdate(Person person);
public List<Person> findAllPersons();
public Person findPerson(Long id);
}
Request Factory
To track entities, we need an entity locator:
Entity Locator:
public class PersonLocator extends Locator<Person,Long> {
@Override
public Person create(Class<? extends Person> clazz) {
return new Person();
}
@Override
public Person find(Class<? extends Person> clazz, Long id) {
return PersonDAO.find(id);
}
//more abstract methods to override…
}
Request Factory
To instantiate the services, we need a service
locator:
ServiceLocator:
public class MyServiceLocator implements ServiceLocator {
@Override
public Object getInstance(Class<?> clazz) {
try {
return clazz.newInstance();
} catch ( //Damn you checked exceptions!!! ){
}
}
}
Request Factory
Summary:
» Entities
 Your JPA/JPO entities

» Entity Proxy
 RequestFactory equivalents for your entities

» Value Proxy
 RequestFactory equivalents for your pojos

» Request Context
 Interfaces declaring your exposed services

» Entity Locators
 An API that allows RequestFactroy to interact with the domain world

» Service Locators
 An API that allows RequestFactroy to instantiate your servcies
ServiceLayerDecorator
How does it work?
Meet the ServiceLayerDecorator:
A Chain of decorators:
 Determines how RF interacts with the Domain world
 Creates objects
 Handles domain / proxy / domain mappings
 Handles method invocations
We can override it ;-)
ServiceLayerDecorator
What can we do with it?

» Override default behaviors such as:
 Instantiating locators
 Instantiating service locators
 Instantiating services
 Domain / Proxy / Domain mapping
 Domain method invocations
 AOP like behavior
ServiceLayerDecorator
Instantiate a service with Guice:

» Extend RequestFactoryServlet
» Create a ServiceLayerDecorator with access to
your Guice injector
» Override the createServiceInstance method
ServiceLayerDecorator
Extended RequestFactory Servlet:
public class GuiceRequestFactoryServlet extends RequestFactoryServlet {
public GuiceRequestFactoryServlet() {
super(new DefaultExceptionHandler(), new GuiceServiceLayerDecorator());
}
}
ServiceLayerDecorator
Guicified ServiceLayerDecorator:
public class GuiceServiceLayerDecorator extends ServiceLayerDecorator {
private Injector injector = MyGuiceFactory.getInjector();
@Override
public Object createServiceInstance (Class<? extends RequestContext> clazz) {
Class<?> serviceClass = getTop().resolveServiceClass(clazz);
try {
return injector.getInstance(clazz);
} catch (RuntimeException e) {
return super.createServiceInstance(requestContext);
}
}

}
ServiceLayerDecorator
Instantiate an entity Locator with Spring:

» Extend RequestFactoryServlet
» Create a ServiceLayerDecorator with access to
your Spring context
» Override the createLocator method
ServiceLayerDecorator
Extended RequestFactory Servlet:
public class SpringRequestFactoryServlet extends RequestFactoryServlet {
public SpringRequestFactoryServlet() {
super(new DefaultExceptionHandler(), new SpringServiceLayerDecorator());
}
}
ServiceLayerDecorator
Springified ServiceLayerDecorator:
public class SpringServiceLayerDecorator extends ServiceLayerDecorator
private final ApplicationContext applicationContext;
public SpringServiceLayerDecorator(){
this.applicationContext = WebApplicationContextUtils.getWebApplicationContext(
SpringRequestFactoryServlet.getThreadLocalServletContext());
}
@Override
public <T extends Locator<?, ?>> T createLocator(Class<T> clazz) {
try {
return applicationContext.getBean(clazz);
} catch (BeansException e) {
return super.createLocator(clazz);
}
}
}
Calculated Fields
Execute business method on entity proxies

» Every proxy method must have a domain entity
equivalent method
» Override this behavior with the
ServiceLayerDecorator
Calculated Fields
JPA Entity:

Entity Proxy:

@Entity
public class Person {

@ProxyFor(value=Person.class, locator=SomeLocator.class)
public interface PersonProxy extends EntityProxy {

@Id
private Long id;
private Integer version;
private String firstName
private String lastName

@Embedded
private Address address;
...

Long getId();
Integer getVersion();
String getFirstName();
String getLastName();
//Doesn’t exist in domain entity
String getDisplayName();
//ValueProxy
AddressProxy getAddress();
...

}
}
Calculated Fields
Proxy modification:
@SkipInterfaceValidation
@ProxyFor(value=Person.class, locator=SomeLocator.class)
public interface PersonProxy extends BaseEntityProxy {

Long getId();
Integer getVersion();
String getFirstName();
String getLastName();
@CalculatedField(SomeOtherSerivce.class)
String getDisplayName();
//ValueProxy
AddressProxy getAddress();
...
}
Calculated Fields
SLD Modification:
public class MyServiceLayerDecorator extends ServiceLayerDecorator{
//code is simplified due to size limits…
@Override
public Object getProperty(Object domainObject, String property) {
try {
return super.getProperty(domainObject, property);
} catch (Throwable t) {
Class<? extends BaseEntityProxy> clientClass =
super.resolveClientType(domainObject.getClass(), BaseEntityProxy.class, false);
Method proxyMethod = clientClass.getDeclaredMethod(methodName);
CalculatedField annotation = proxyMethod.getAnnotation(CalculatedField.class);
Class<?> value = annotation.value();
Method domainMethod =
value.getDeclaredMethod(methodName,domainObject.getClass());
domainMethod.setAccessible(true);
return domainMethod.invoke(injector.getInstance(value), domainObject);
}
Enhanced Request Factory
What else can we do?

» RequestContext Inheritance
» Generify the EntityLocator
» JSR 303
RequestContext Inheritance
Remove the Boilerplate:

» You can inherit a RequestContext
» You can use Generics, but with limitations:
 Method parameter cannot be generic, casting is
required
 Method return type can be generic
RequestContext Inheritance
Generic RequestContext:
public interface BasicRequestContext<T extends BaseEntityProxy>
extends RequestContext {
Request<Void> saveOrUpdate (BaseEntityProxy entityProxy);
Request<T> find(Long id);
}

Actual RequestContext:
@Service(value=PersonDAO.class,locator = MyServiceLocator.class)
public interface PersonRequest extends BasicRequestContext<PersonProxy>{
}
Generic EntityLocator
One EntityLocator for all of your entities:
@Component
public class BaseEntityLocator extends Locator<BaseEntity, Long> {
@Autowired
private BaseDAO baseDAO;
@Override
public BaseEntity create(Class<? extends BaseEntity > clazz) {
return clazz.newInstance();
}
@Override
public BaseEntity find(Class<? extends BaseEntity > clazz, Long id) {
return (BaseEntity) baseDAO.find(aLong, aClass);
}
//more abstract methods to override…
JSR 303
Validations? Just add water:
Server entity:

Client side invocation:

@Entity
public class Person {
@Id
private Long id;
private Integer version;

PersonProxy person = personRequest.create(PersonProxy.class);
someEntityProxy.setfName(null);
someEntityProxy.setlName("Garon");
someRequest.save(someEntityProxy).fire(new Receiver<Void>() {
@Override
public void onSuccess(Void response) {
}

@NotNull
private String firstName
private String lastName

@Override
public void onConstraintViolation(Set<ConstraintViolation<?>>
violations) {
//Handle the violations
}

@Embedded
private Address address;
...

}

});
THE REQUESTBUILDER
Request Builder
RequestBuilder in a nutshell:

» Generic HTTP Requests
» Transports text
» Same Origin Policy
Request Builder
What can we use if for?

» Consume data from external site
» Interact with lightweight text based services
» Download files (creativity required)
Request Builder
Simple service example:
public void executeQuery(String url, AsyncCallback<String>callback){
String url = “http://javaedge.com/ws/getSpeakersList/json”

RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);
builder.sendRequest(null, new RequestCallback() {
public void onResponseReceived(Request request, Response response) {
String response = response.getText()
callback.onSuccess(response);
}
});
}
Request Builder
File download flow example:
Send Http GET
Request Using
RequestBuilder

Return URL to file in
HTTP Response

Open a new window with the
file URL
(GET Request)

Fetch file from Filesystem and
prepare a temporary url to file

Parse returned url from
RequestBuilder Response

Client Side
Server Side
Request Builder
AutoBean Framework:

» Support easy encoding of Pojos to JSON
structures
» Usable in non-GWT code
 com.google.web.bindery

» Used in RequestFactory
Request Builder
AutoBean declaration:
public interface Person {
String getFirstName();
void setFirstName(String firstName);
String getLastName();
void setLastName(String lastName);
}

AutoBean Factory declaration:
public interface MyFactory extends AutoBeanFactory {
AutoBean<Person> person();
}
Request Builder
Using the Framework:
//Creating an AutoBean
public Person createPerson(){
MyFactory factory = GWT.create(MyFactory.class);
AutoBean<Person> person = factory.person();
return person.as();
}
//Serializing a bean to JSON
String serializeToJson(Person person) {
AutoBean<Person> bean = AutoBeanUtils.getAutoBean(person);
return AutoBeanCodex.encode(bean).getPayload();
}
// Deserializing a bean from JSON
Person deserializeFromJson(String json) {
AutoBean<Person> bean = AutoBeanCodex.decode(factory, Person.class, json);
return bean.as();
}
WIRING IT ALL TOGETHER
Guice your GWT App
Required ingredients:

» Server Side:

»

 1 x Guice Servlet Context Listener
 1 x Guice Servlet Module
 1 x RequestFactory Servlet
 1 x Dispatcher Servlet
Web.xml:
 1 x Guice Filter
Guice your GWT App
ContextListener:
public class MyContextListener extends GuiceServletContextListener{
@Override
protected Injector getInjector() {
return Guice.createInjector(new MyServletModule());
}
}

ServletModule:
public class MyServletModule extends ServletModule {
@Override
protected void configureServlets() {
serve(“rf_url”).with(MyRequestFactoryServlet.class);
serve(“rpc_ul”).with(MyDisptacherSerlet.class);
Multibinder<ServiceLayerDecorator> binder = Multibinder.newSetBinder(binder(),
ServiceLayerDecorator.class);
binder.addBinding().to(MyServiceLayerDecorator.class);
}
}
Guice your GWT App
Web.xml:
<web-app>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</ url-pattern >
</filter-class>

<listener>
<listener-class>com.alphacsp.theedge.server.MyContextListener</listener-class>
</filter-class>
…
</ web-app >
Spring your GWT App
Required ingredients:

» Server Side:

»

 1 x RequestFactory Servlet
 1 x Dispatcher Servlet
Web.xml:
 1 x Spring Dispatcher Servlet
Spring your GWT App
Web.xml:
<web-app>
<servlet>
<servlet-name>SpringGWT</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringGWT</servlet-name>
<url-pattern>your_url_mapping</url-pattern>
</servlet-mapping>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</filter-class>
…
</ web-app >
Spring your GWT App
Application context:
<beans>
<context:component-scan base-package="com.alphacsp.theedge "/>
<mvc:annotation-driven/>
</beans>

RequestFactory Servlet:
@Controller
public class SpringRequestFactoryServlet extends RequestFactoryServlet {
@Autowired
public SpringRequestFactoryServlet (ServiceLayerDecorator... serviceDecorators){
super(new DefaultExceptionHandler(), serviceDecorators);
}
@Override
@RequestMapping("/rf")
protected void doPost(HttpServletRequest request, HttpServletResponse response){
super.doPost(request, response);
}
}
RESOURCES
Resources
GWT RPC
» Official Docs :

https://developers.google.com/webtoolkit/doc/latest/tutorial/RPC
» Command Pattern:

▪ http://www.google.com/events/io/2009/sessions/Go
ogleWebToolkitBestPractices.html (YouTube)
▪ http://code.google.com/p/gwtplatform/wiki/GettingStartedDispatch
▪ http://code.google.com/p/gwt-dispatch/
Resources
RequestFactory

» Official Docs:
https://developers.google.com/webtoolkit/doc/latest/tutorial/RPC
» Lifecycle (Great read):
http://fascynacja.wordpress.com/2011/04/17
/exciting-life-of-entity-proxies-in-contexts-ofrequestfactory/
Resources
GWT Guice Servlet Module

» Official Docs:
http://code.google.com/p/googleguice/wiki/ServletModule
Resources
GWT Spring Integration

» Howto:
▪ http://krams915.blogspot.com/2012/02/spring31-gwt-maven-plugin-and_3309.html
▪ http://crazygui.wordpress.com/2011/12/06/sprin
g-gwt-software-architecture-for-scalableapplications-part-1/
THANK YOU!

Weitere ähnliche Inhalte

Was ist angesagt?

"[WORKSHOP] K8S for developers", Denis Romanuk
"[WORKSHOP] K8S for developers", Denis Romanuk"[WORKSHOP] K8S for developers", Denis Romanuk
"[WORKSHOP] K8S for developers", Denis RomanukFwdays
 
berne.*tesday1
berne.*tesday1berne.*tesday1
berne.*tesday1Anne Starr
 
Sebastien goasguen cloud stack the next year
Sebastien goasguen   cloud stack the next yearSebastien goasguen   cloud stack the next year
Sebastien goasguen cloud stack the next yearShapeBlue
 
The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...
 The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ... The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...
The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...Josef Adersberger
 
5 steps to take setting up a streamlined container pipeline
5 steps to take setting up a streamlined container pipeline5 steps to take setting up a streamlined container pipeline
5 steps to take setting up a streamlined container pipelineMichel Schildmeijer
 
Pro2516 10 things about oracle and k8s.pptx-final
Pro2516   10 things about oracle and k8s.pptx-finalPro2516   10 things about oracle and k8s.pptx-final
Pro2516 10 things about oracle and k8s.pptx-finalMichel Schildmeijer
 
Microcontainers and Tools for Hardcore Container Debugging
Microcontainers and Tools for Hardcore Container DebuggingMicrocontainers and Tools for Hardcore Container Debugging
Microcontainers and Tools for Hardcore Container DebuggingOracle Developers
 
How Class Data Sharing Can Speed up Your Jakarta EE Application Startup
How Class Data Sharing Can Speed up Your Jakarta EE Application StartupHow Class Data Sharing Can Speed up Your Jakarta EE Application Startup
How Class Data Sharing Can Speed up Your Jakarta EE Application StartupRudy De Busscher
 
A New Centralized Volume Storage Solution for Docker and Container Cloud by W...
A New Centralized Volume Storage Solution for Docker and Container Cloud by W...A New Centralized Volume Storage Solution for Docker and Container Cloud by W...
A New Centralized Volume Storage Solution for Docker and Container Cloud by W...Docker, Inc.
 
Nginx conference 2015
Nginx conference 2015Nginx conference 2015
Nginx conference 2015ING-IT
 
Microservices with Node.js and Apache Cassandra
Microservices with Node.js and Apache CassandraMicroservices with Node.js and Apache Cassandra
Microservices with Node.js and Apache CassandraJorge Bay Gondra
 
ElasticKube, a Container Management Platform for Kubernetes
ElasticKube, a Container Management Platform for KubernetesElasticKube, a Container Management Platform for Kubernetes
ElasticKube, a Container Management Platform for KubernetesMatt Baldwin
 
Automating CICD Pipeline with GitLab and Docker Containers for Java Applications
Automating CICD Pipeline with GitLab and Docker Containers for Java ApplicationsAutomating CICD Pipeline with GitLab and Docker Containers for Java Applications
Automating CICD Pipeline with GitLab and Docker Containers for Java ApplicationsJelastic Multi-Cloud PaaS
 
ContainerDays NYC 2015: "Container Orchestration Compared: Kubernetes and Doc...
ContainerDays NYC 2015: "Container Orchestration Compared: Kubernetes and Doc...ContainerDays NYC 2015: "Container Orchestration Compared: Kubernetes and Doc...
ContainerDays NYC 2015: "Container Orchestration Compared: Kubernetes and Doc...DynamicInfraDays
 
Introduction into Docker Containers, the Oracle Platform and the Oracle (Nati...
Introduction into Docker Containers, the Oracle Platform and the Oracle (Nati...Introduction into Docker Containers, the Oracle Platform and the Oracle (Nati...
Introduction into Docker Containers, the Oracle Platform and the Oracle (Nati...Lucas Jellema
 
Netflix0SS Services on Docker
Netflix0SS Services on DockerNetflix0SS Services on Docker
Netflix0SS Services on DockerDocker, Inc.
 
DCEU 18: 5 Patterns for Success in Application Transformation
DCEU 18: 5 Patterns for Success in Application TransformationDCEU 18: 5 Patterns for Success in Application Transformation
DCEU 18: 5 Patterns for Success in Application TransformationDocker, Inc.
 
Container World 2018
Container World 2018Container World 2018
Container World 2018aspyker
 
Webcast - Making kubernetes production ready
Webcast - Making kubernetes production readyWebcast - Making kubernetes production ready
Webcast - Making kubernetes production readyApplatix
 

Was ist angesagt? (20)

"[WORKSHOP] K8S for developers", Denis Romanuk
"[WORKSHOP] K8S for developers", Denis Romanuk"[WORKSHOP] K8S for developers", Denis Romanuk
"[WORKSHOP] K8S for developers", Denis Romanuk
 
berne.*tesday1
berne.*tesday1berne.*tesday1
berne.*tesday1
 
Sebastien goasguen cloud stack the next year
Sebastien goasguen   cloud stack the next yearSebastien goasguen   cloud stack the next year
Sebastien goasguen cloud stack the next year
 
The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...
 The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ... The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...
The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...
 
5 steps to take setting up a streamlined container pipeline
5 steps to take setting up a streamlined container pipeline5 steps to take setting up a streamlined container pipeline
5 steps to take setting up a streamlined container pipeline
 
Pro2516 10 things about oracle and k8s.pptx-final
Pro2516   10 things about oracle and k8s.pptx-finalPro2516   10 things about oracle and k8s.pptx-final
Pro2516 10 things about oracle and k8s.pptx-final
 
Microcontainers and Tools for Hardcore Container Debugging
Microcontainers and Tools for Hardcore Container DebuggingMicrocontainers and Tools for Hardcore Container Debugging
Microcontainers and Tools for Hardcore Container Debugging
 
How Class Data Sharing Can Speed up Your Jakarta EE Application Startup
How Class Data Sharing Can Speed up Your Jakarta EE Application StartupHow Class Data Sharing Can Speed up Your Jakarta EE Application Startup
How Class Data Sharing Can Speed up Your Jakarta EE Application Startup
 
A New Centralized Volume Storage Solution for Docker and Container Cloud by W...
A New Centralized Volume Storage Solution for Docker and Container Cloud by W...A New Centralized Volume Storage Solution for Docker and Container Cloud by W...
A New Centralized Volume Storage Solution for Docker and Container Cloud by W...
 
Nginx conference 2015
Nginx conference 2015Nginx conference 2015
Nginx conference 2015
 
WebLogic and GraalVM
WebLogic and GraalVMWebLogic and GraalVM
WebLogic and GraalVM
 
Microservices with Node.js and Apache Cassandra
Microservices with Node.js and Apache CassandraMicroservices with Node.js and Apache Cassandra
Microservices with Node.js and Apache Cassandra
 
ElasticKube, a Container Management Platform for Kubernetes
ElasticKube, a Container Management Platform for KubernetesElasticKube, a Container Management Platform for Kubernetes
ElasticKube, a Container Management Platform for Kubernetes
 
Automating CICD Pipeline with GitLab and Docker Containers for Java Applications
Automating CICD Pipeline with GitLab and Docker Containers for Java ApplicationsAutomating CICD Pipeline with GitLab and Docker Containers for Java Applications
Automating CICD Pipeline with GitLab and Docker Containers for Java Applications
 
ContainerDays NYC 2015: "Container Orchestration Compared: Kubernetes and Doc...
ContainerDays NYC 2015: "Container Orchestration Compared: Kubernetes and Doc...ContainerDays NYC 2015: "Container Orchestration Compared: Kubernetes and Doc...
ContainerDays NYC 2015: "Container Orchestration Compared: Kubernetes and Doc...
 
Introduction into Docker Containers, the Oracle Platform and the Oracle (Nati...
Introduction into Docker Containers, the Oracle Platform and the Oracle (Nati...Introduction into Docker Containers, the Oracle Platform and the Oracle (Nati...
Introduction into Docker Containers, the Oracle Platform and the Oracle (Nati...
 
Netflix0SS Services on Docker
Netflix0SS Services on DockerNetflix0SS Services on Docker
Netflix0SS Services on Docker
 
DCEU 18: 5 Patterns for Success in Application Transformation
DCEU 18: 5 Patterns for Success in Application TransformationDCEU 18: 5 Patterns for Success in Application Transformation
DCEU 18: 5 Patterns for Success in Application Transformation
 
Container World 2018
Container World 2018Container World 2018
Container World 2018
 
Webcast - Making kubernetes production ready
Webcast - Making kubernetes production readyWebcast - Making kubernetes production ready
Webcast - Making kubernetes production ready
 

Ähnlich wie GWT Enterprise Edition

WinAppDriver Development
WinAppDriver DevelopmentWinAppDriver Development
WinAppDriver DevelopmentJeremy Kao
 
Session 29 - Servlets - Part 5
Session 29 - Servlets - Part 5Session 29 - Servlets - Part 5
Session 29 - Servlets - Part 5PawanMM
 
Domain-Driven Design with SeedStack
Domain-Driven Design with SeedStackDomain-Driven Design with SeedStack
Domain-Driven Design with SeedStackSeedStack
 
Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Joe Keeley
 
GWT Web Socket and data serialization
GWT Web Socket and data serializationGWT Web Socket and data serialization
GWT Web Socket and data serializationGWTcon
 
Web services in java
Web services in javaWeb services in java
Web services in javamaabujji
 
5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)Christian Rokitta
 
Spring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. RESTSpring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. RESTSam Brannen
 
Managing user's data with Spring Session
Managing user's data with Spring SessionManaging user's data with Spring Session
Managing user's data with Spring SessionDavid Gómez García
 
Using Java to implement SOAP Web Services: JAX-WS
Using Java to implement SOAP Web Services: JAX-WS�Using Java to implement SOAP Web Services: JAX-WS�
Using Java to implement SOAP Web Services: JAX-WSKatrien Verbert
 
Soa development using javascript
Soa development using javascriptSoa development using javascript
Soa development using javascriptDsixE Inc
 
Ring: Web Apps in Idiomatic Clojure
Ring: Web Apps in Idiomatic ClojureRing: Web Apps in Idiomatic Clojure
Ring: Web Apps in Idiomatic ClojureMark McGranaghan
 
HTTP Whiteboard - OSGI Compendium 6.0 - How web apps should have been! - R Auge
HTTP Whiteboard - OSGI Compendium 6.0 - How web apps should have been! - R AugeHTTP Whiteboard - OSGI Compendium 6.0 - How web apps should have been! - R Auge
HTTP Whiteboard - OSGI Compendium 6.0 - How web apps should have been! - R Augemfrancis
 
Java Web Programming [2/9] : Servlet Basic
Java Web Programming [2/9] : Servlet BasicJava Web Programming [2/9] : Servlet Basic
Java Web Programming [2/9] : Servlet BasicIMC Institute
 
A real-world Relay application in production - Stefano Masini - Codemotion Am...
A real-world Relay application in production - Stefano Masini - Codemotion Am...A real-world Relay application in production - Stefano Masini - Codemotion Am...
A real-world Relay application in production - Stefano Masini - Codemotion Am...Codemotion
 

Ähnlich wie GWT Enterprise Edition (20)

WinAppDriver Development
WinAppDriver DevelopmentWinAppDriver Development
WinAppDriver Development
 
Session 29 - Servlets - Part 5
Session 29 - Servlets - Part 5Session 29 - Servlets - Part 5
Session 29 - Servlets - Part 5
 
Domain-Driven Design with SeedStack
Domain-Driven Design with SeedStackDomain-Driven Design with SeedStack
Domain-Driven Design with SeedStack
 
Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019
 
Android dev 3
Android dev 3Android dev 3
Android dev 3
 
GWT Web Socket and data serialization
GWT Web Socket and data serializationGWT Web Socket and data serialization
GWT Web Socket and data serialization
 
11-DWR-and-JQuery
11-DWR-and-JQuery11-DWR-and-JQuery
11-DWR-and-JQuery
 
11-DWR-and-JQuery
11-DWR-and-JQuery11-DWR-and-JQuery
11-DWR-and-JQuery
 
Web services in java
Web services in javaWeb services in java
Web services in java
 
5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)
 
Spring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. RESTSpring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. REST
 
Managing user's data with Spring Session
Managing user's data with Spring SessionManaging user's data with Spring Session
Managing user's data with Spring Session
 
Lecture 2
Lecture 2Lecture 2
Lecture 2
 
Using Java to implement SOAP Web Services: JAX-WS
Using Java to implement SOAP Web Services: JAX-WS�Using Java to implement SOAP Web Services: JAX-WS�
Using Java to implement SOAP Web Services: JAX-WS
 
Soa development using javascript
Soa development using javascriptSoa development using javascript
Soa development using javascript
 
Ring: Web Apps in Idiomatic Clojure
Ring: Web Apps in Idiomatic ClojureRing: Web Apps in Idiomatic Clojure
Ring: Web Apps in Idiomatic Clojure
 
HTTP Whiteboard - OSGI Compendium 6.0 - How web apps should have been! - R Auge
HTTP Whiteboard - OSGI Compendium 6.0 - How web apps should have been! - R AugeHTTP Whiteboard - OSGI Compendium 6.0 - How web apps should have been! - R Auge
HTTP Whiteboard - OSGI Compendium 6.0 - How web apps should have been! - R Auge
 
Java Web Programming [2/9] : Servlet Basic
Java Web Programming [2/9] : Servlet BasicJava Web Programming [2/9] : Servlet Basic
Java Web Programming [2/9] : Servlet Basic
 
Exploring Relay land
Exploring Relay landExploring Relay land
Exploring Relay land
 
A real-world Relay application in production - Stefano Masini - Codemotion Am...
A real-world Relay application in production - Stefano Masini - Codemotion Am...A real-world Relay application in production - Stefano Masini - Codemotion Am...
A real-world Relay application in production - Stefano Masini - Codemotion Am...
 

Kürzlich hochgeladen

Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 

Kürzlich hochgeladen (20)

Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 

GWT Enterprise Edition

  • 2. Agenda Overview: » Vanilla GWT » Improved RPC » Enhanced Request Factory » Request Builder » Tying it all together
  • 4. Vanilla GWT Server Side The Lowdown on GWT RMI: » Communication is always asynchronous » Client side code is Java translated to JavaScript » Server side code is based on GWT Servlets
  • 5. Vanilla GWT Server Side Three Flavors of RMI: » GWT RPC » »  Service oriented RequestFactory  Data oriented RequestBuilder  Manual HTTP Requests
  • 6. Vanilla GWT RMI GWT server side application: RemoteServiceServlet RequestFactoryServlet HttpServlet GWT Application WAR HTTP (Async)
  • 7. Vanilla GWT Server Side Use case examples: » GWT RPC » »  Standalone services: Authentication RequestFactory  Data services: Domain entity CRUD operations RequestBuilder  Cross site integration: Reading data from a remote server
  • 9. Vanilla RPC GWT-RPC in a nutshell: » Each service is a standalone RPC Servlet » Client invokes a generated interface » Transports concrete java objects
  • 10. Vanilla RPC How can we improve it? » Use the command pattern  Use a single RPC Servlet for all of your services » Integrate with an IoC container  Wire all of your services easily » Don’t use interfaces, use only concrete classes
  • 11. Command Pattern Meet the Command Pattern: » A Single RPC Servlet for all of your services » Action class represents the client request » Result class represents the server response » ActionHandler class handles the Action and returns the Result
  • 12. Command Pattern Architecture Dispatcher RPC Servlet Client Browser Action Handler Action Dispatch Service Action Result Async Dispatcher Action Result
  • 13. Command Pattern Benefits: » Server side:  Single RPC Servlet for all services » Client side:     Caching Batching Centralized failure handling Undo / Redo support Don’t reinvent the wheel, use existing frameworks:  GWTP  GWT-Dispatch
  • 14. Command Pattern, Example Action: public class GetDocumentByIDAction extends Action<GetDocumentByIDResult> { private String id; public String getId() { return id; } } Result: public class GetDocumentByIDResult implements Result { private String documentContents; public String getDocument() { return documentContents; } }
  • 15. Command Pattern ActionHandler: public class GetDocummentByIDActionHandler implements ActionHandler<GetDocummentByIDAction, GetDocummentByIDResult> { DocumentService documentService; @Override public GetDocummentByIDResult execute(GetDocummentByIDAction action) { String doc = documentService.getDocumentById(action.getId()); return new GetDocummentByIDResult (doc); } }
  • 16. IoC / DI Integrate with an IoC container: » Central point for configuration: » »  Services  DAO Minimizes the amount of code in your application  Inject what you need Make your application more testable  Easy way to create mockup objects
  • 17. Spring Integration Simple Spring example: public class MyRPCServiceImpl extends RemoteServiceServlet implements MyRPCService { private ApplicationContext applicationContext; @Override public void init() { super.init() ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext (getServletContext()); } @Override public String doSomething() { return applicationContext.getBean(SpringRPCService.class).doSomething(); } }
  • 18. Guice Integration Guiceified Servlet: public class MyRPCImpl extends RemoteServiceServlet implements MyRPC { private final SomeService service; public MyRPCImpl(){ this.service = MyGuiceFactory.getInjector().getInstance(SomeService.class); } @Override public String doSomething() { return service.doSomething(); } }
  • 19. Summary So far we’ve seen: » Command pattern  Reduces number of RPC servlets  Allows for smart RMI » IoC Integration  Enables single bootstrap  Allows Dependency Injection
  • 20. DIY RPC: What else can we do? Replace the entire RPC mechanism: » GWT offers static methods to process RPC » We can use it to create our own RPC Servlets implementations
  • 21. DIY RPC: HttpServlet.doPost() HttpServletRequest request RPCServletUtils. readContentAsGwtRpc(request) String payload Invoke Method by reflection using: • • rpcRequest.getMethod() rpcRequest.getParameters() RPCRequest request RPC.decodeRequest(p ayload,…) Object result RPC.encodeResponseForSuccess (rpcRequest.getMethod(), result, serializationPolicy, serializationFlags); String payload RPCServletUtils.writeResponse (getServletContext(), response, payload, gzipEncode)
  • 23. Request Factory RequestFactory in a nutshell: » Designed for Data oriented services » Lightweight » Integrates with any ORM framework
  • 24. Request Factory Created for data oriented services: » Uses proxies as Data Transfer objects » Uses JSON as a transport layer » Transfers shallow object graph » Tracks your domain objects, transfers only delta changes » Loosely coupled with your sever side
  • 25. Request Factory The main players: Domain definition RequestFactory equivalent Entity EntityProxy POJO ValueProxy Service definitions RequestContext Service implementations N/A
  • 26. Request Factory Other players: » Entity Locators ▪ A way to track domain entities » Service Locators ▪ A way to instantiate domain services
  • 27. Request Factory Entity mappings: JPA Entity: Entity Proxy: @Entity public class Person { @Id private Long id; private Integer version; private String firstName private String lastName @ProxyFor(value=Person.class, locator=MyLocator.class) public interface PersonProxy extends EntityProxy { Long getId(); Integer getVersion(); String getFirstName(); String getLastName(); @Embedded private Address address; ... } //ValueProxy AddressProxy getAddress(); ... }
  • 28. Request Factory RequestContext: @Service(value=PersonDAO.class,locator = MyServiceLocator.class) public interface PersonRequest extends RequestContext { Request<Void> saveOrUpdate(PersonProxy person); Request<List<PersonProxy>> findAllPersons(); Request<PersonProxy> findPerson(Long id); } Our actual service: public class PersonDAO { public void saveOrUpdate(Person person); public List<Person> findAllPersons(); public Person findPerson(Long id); }
  • 29. Request Factory To track entities, we need an entity locator: Entity Locator: public class PersonLocator extends Locator<Person,Long> { @Override public Person create(Class<? extends Person> clazz) { return new Person(); } @Override public Person find(Class<? extends Person> clazz, Long id) { return PersonDAO.find(id); } //more abstract methods to override… }
  • 30. Request Factory To instantiate the services, we need a service locator: ServiceLocator: public class MyServiceLocator implements ServiceLocator { @Override public Object getInstance(Class<?> clazz) { try { return clazz.newInstance(); } catch ( //Damn you checked exceptions!!! ){ } } }
  • 31. Request Factory Summary: » Entities  Your JPA/JPO entities » Entity Proxy  RequestFactory equivalents for your entities » Value Proxy  RequestFactory equivalents for your pojos » Request Context  Interfaces declaring your exposed services » Entity Locators  An API that allows RequestFactroy to interact with the domain world » Service Locators  An API that allows RequestFactroy to instantiate your servcies
  • 32. ServiceLayerDecorator How does it work? Meet the ServiceLayerDecorator: A Chain of decorators:  Determines how RF interacts with the Domain world  Creates objects  Handles domain / proxy / domain mappings  Handles method invocations We can override it ;-)
  • 33. ServiceLayerDecorator What can we do with it? » Override default behaviors such as:  Instantiating locators  Instantiating service locators  Instantiating services  Domain / Proxy / Domain mapping  Domain method invocations  AOP like behavior
  • 34. ServiceLayerDecorator Instantiate a service with Guice: » Extend RequestFactoryServlet » Create a ServiceLayerDecorator with access to your Guice injector » Override the createServiceInstance method
  • 35. ServiceLayerDecorator Extended RequestFactory Servlet: public class GuiceRequestFactoryServlet extends RequestFactoryServlet { public GuiceRequestFactoryServlet() { super(new DefaultExceptionHandler(), new GuiceServiceLayerDecorator()); } }
  • 36. ServiceLayerDecorator Guicified ServiceLayerDecorator: public class GuiceServiceLayerDecorator extends ServiceLayerDecorator { private Injector injector = MyGuiceFactory.getInjector(); @Override public Object createServiceInstance (Class<? extends RequestContext> clazz) { Class<?> serviceClass = getTop().resolveServiceClass(clazz); try { return injector.getInstance(clazz); } catch (RuntimeException e) { return super.createServiceInstance(requestContext); } } }
  • 37. ServiceLayerDecorator Instantiate an entity Locator with Spring: » Extend RequestFactoryServlet » Create a ServiceLayerDecorator with access to your Spring context » Override the createLocator method
  • 38. ServiceLayerDecorator Extended RequestFactory Servlet: public class SpringRequestFactoryServlet extends RequestFactoryServlet { public SpringRequestFactoryServlet() { super(new DefaultExceptionHandler(), new SpringServiceLayerDecorator()); } }
  • 39. ServiceLayerDecorator Springified ServiceLayerDecorator: public class SpringServiceLayerDecorator extends ServiceLayerDecorator private final ApplicationContext applicationContext; public SpringServiceLayerDecorator(){ this.applicationContext = WebApplicationContextUtils.getWebApplicationContext( SpringRequestFactoryServlet.getThreadLocalServletContext()); } @Override public <T extends Locator<?, ?>> T createLocator(Class<T> clazz) { try { return applicationContext.getBean(clazz); } catch (BeansException e) { return super.createLocator(clazz); } } }
  • 40. Calculated Fields Execute business method on entity proxies » Every proxy method must have a domain entity equivalent method » Override this behavior with the ServiceLayerDecorator
  • 41. Calculated Fields JPA Entity: Entity Proxy: @Entity public class Person { @ProxyFor(value=Person.class, locator=SomeLocator.class) public interface PersonProxy extends EntityProxy { @Id private Long id; private Integer version; private String firstName private String lastName @Embedded private Address address; ... Long getId(); Integer getVersion(); String getFirstName(); String getLastName(); //Doesn’t exist in domain entity String getDisplayName(); //ValueProxy AddressProxy getAddress(); ... } }
  • 42. Calculated Fields Proxy modification: @SkipInterfaceValidation @ProxyFor(value=Person.class, locator=SomeLocator.class) public interface PersonProxy extends BaseEntityProxy { Long getId(); Integer getVersion(); String getFirstName(); String getLastName(); @CalculatedField(SomeOtherSerivce.class) String getDisplayName(); //ValueProxy AddressProxy getAddress(); ... }
  • 43. Calculated Fields SLD Modification: public class MyServiceLayerDecorator extends ServiceLayerDecorator{ //code is simplified due to size limits… @Override public Object getProperty(Object domainObject, String property) { try { return super.getProperty(domainObject, property); } catch (Throwable t) { Class<? extends BaseEntityProxy> clientClass = super.resolveClientType(domainObject.getClass(), BaseEntityProxy.class, false); Method proxyMethod = clientClass.getDeclaredMethod(methodName); CalculatedField annotation = proxyMethod.getAnnotation(CalculatedField.class); Class<?> value = annotation.value(); Method domainMethod = value.getDeclaredMethod(methodName,domainObject.getClass()); domainMethod.setAccessible(true); return domainMethod.invoke(injector.getInstance(value), domainObject); }
  • 44. Enhanced Request Factory What else can we do? » RequestContext Inheritance » Generify the EntityLocator » JSR 303
  • 45. RequestContext Inheritance Remove the Boilerplate: » You can inherit a RequestContext » You can use Generics, but with limitations:  Method parameter cannot be generic, casting is required  Method return type can be generic
  • 46. RequestContext Inheritance Generic RequestContext: public interface BasicRequestContext<T extends BaseEntityProxy> extends RequestContext { Request<Void> saveOrUpdate (BaseEntityProxy entityProxy); Request<T> find(Long id); } Actual RequestContext: @Service(value=PersonDAO.class,locator = MyServiceLocator.class) public interface PersonRequest extends BasicRequestContext<PersonProxy>{ }
  • 47. Generic EntityLocator One EntityLocator for all of your entities: @Component public class BaseEntityLocator extends Locator<BaseEntity, Long> { @Autowired private BaseDAO baseDAO; @Override public BaseEntity create(Class<? extends BaseEntity > clazz) { return clazz.newInstance(); } @Override public BaseEntity find(Class<? extends BaseEntity > clazz, Long id) { return (BaseEntity) baseDAO.find(aLong, aClass); } //more abstract methods to override…
  • 48. JSR 303 Validations? Just add water: Server entity: Client side invocation: @Entity public class Person { @Id private Long id; private Integer version; PersonProxy person = personRequest.create(PersonProxy.class); someEntityProxy.setfName(null); someEntityProxy.setlName("Garon"); someRequest.save(someEntityProxy).fire(new Receiver<Void>() { @Override public void onSuccess(Void response) { } @NotNull private String firstName private String lastName @Override public void onConstraintViolation(Set<ConstraintViolation<?>> violations) { //Handle the violations } @Embedded private Address address; ... } });
  • 50. Request Builder RequestBuilder in a nutshell: » Generic HTTP Requests » Transports text » Same Origin Policy
  • 51. Request Builder What can we use if for? » Consume data from external site » Interact with lightweight text based services » Download files (creativity required)
  • 52. Request Builder Simple service example: public void executeQuery(String url, AsyncCallback<String>callback){ String url = “http://javaedge.com/ws/getSpeakersList/json” RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url); builder.sendRequest(null, new RequestCallback() { public void onResponseReceived(Request request, Response response) { String response = response.getText() callback.onSuccess(response); } }); }
  • 53. Request Builder File download flow example: Send Http GET Request Using RequestBuilder Return URL to file in HTTP Response Open a new window with the file URL (GET Request) Fetch file from Filesystem and prepare a temporary url to file Parse returned url from RequestBuilder Response Client Side Server Side
  • 54. Request Builder AutoBean Framework: » Support easy encoding of Pojos to JSON structures » Usable in non-GWT code  com.google.web.bindery » Used in RequestFactory
  • 55. Request Builder AutoBean declaration: public interface Person { String getFirstName(); void setFirstName(String firstName); String getLastName(); void setLastName(String lastName); } AutoBean Factory declaration: public interface MyFactory extends AutoBeanFactory { AutoBean<Person> person(); }
  • 56. Request Builder Using the Framework: //Creating an AutoBean public Person createPerson(){ MyFactory factory = GWT.create(MyFactory.class); AutoBean<Person> person = factory.person(); return person.as(); } //Serializing a bean to JSON String serializeToJson(Person person) { AutoBean<Person> bean = AutoBeanUtils.getAutoBean(person); return AutoBeanCodex.encode(bean).getPayload(); } // Deserializing a bean from JSON Person deserializeFromJson(String json) { AutoBean<Person> bean = AutoBeanCodex.decode(factory, Person.class, json); return bean.as(); }
  • 57. WIRING IT ALL TOGETHER
  • 58. Guice your GWT App Required ingredients: » Server Side: »  1 x Guice Servlet Context Listener  1 x Guice Servlet Module  1 x RequestFactory Servlet  1 x Dispatcher Servlet Web.xml:  1 x Guice Filter
  • 59. Guice your GWT App ContextListener: public class MyContextListener extends GuiceServletContextListener{ @Override protected Injector getInjector() { return Guice.createInjector(new MyServletModule()); } } ServletModule: public class MyServletModule extends ServletModule { @Override protected void configureServlets() { serve(“rf_url”).with(MyRequestFactoryServlet.class); serve(“rpc_ul”).with(MyDisptacherSerlet.class); Multibinder<ServiceLayerDecorator> binder = Multibinder.newSetBinder(binder(), ServiceLayerDecorator.class); binder.addBinding().to(MyServiceLayerDecorator.class); } }
  • 60. Guice your GWT App Web.xml: <web-app> <filter> <filter-name>guiceFilter</filter-name> <filter-class>com.google.inject.servlet.GuiceFilter</filter-class> </filter> <filter-mapping> <filter-name>guiceFilter</filter-name> <url-pattern>/*</ url-pattern > </filter-class> <listener> <listener-class>com.alphacsp.theedge.server.MyContextListener</listener-class> </filter-class> … </ web-app >
  • 61. Spring your GWT App Required ingredients: » Server Side: »  1 x RequestFactory Servlet  1 x Dispatcher Servlet Web.xml:  1 x Spring Dispatcher Servlet
  • 62. Spring your GWT App Web.xml: <web-app> <servlet> <servlet-name>SpringGWT</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SpringGWT</servlet-name> <url-pattern>your_url_mapping</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </filter-class> … </ web-app >
  • 63. Spring your GWT App Application context: <beans> <context:component-scan base-package="com.alphacsp.theedge "/> <mvc:annotation-driven/> </beans> RequestFactory Servlet: @Controller public class SpringRequestFactoryServlet extends RequestFactoryServlet { @Autowired public SpringRequestFactoryServlet (ServiceLayerDecorator... serviceDecorators){ super(new DefaultExceptionHandler(), serviceDecorators); } @Override @RequestMapping("/rf") protected void doPost(HttpServletRequest request, HttpServletResponse response){ super.doPost(request, response); } }
  • 65. Resources GWT RPC » Official Docs : https://developers.google.com/webtoolkit/doc/latest/tutorial/RPC » Command Pattern: ▪ http://www.google.com/events/io/2009/sessions/Go ogleWebToolkitBestPractices.html (YouTube) ▪ http://code.google.com/p/gwtplatform/wiki/GettingStartedDispatch ▪ http://code.google.com/p/gwt-dispatch/
  • 66. Resources RequestFactory » Official Docs: https://developers.google.com/webtoolkit/doc/latest/tutorial/RPC » Lifecycle (Great read): http://fascynacja.wordpress.com/2011/04/17 /exciting-life-of-entity-proxies-in-contexts-ofrequestfactory/
  • 67. Resources GWT Guice Servlet Module » Official Docs: http://code.google.com/p/googleguice/wiki/ServletModule
  • 68. Resources GWT Spring Integration » Howto: ▪ http://krams915.blogspot.com/2012/02/spring31-gwt-maven-plugin-and_3309.html ▪ http://crazygui.wordpress.com/2011/12/06/sprin g-gwt-software-architecture-for-scalableapplications-part-1/