GWT@Jazoon08 - Part 2/6 - Attentive Service

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    2 Favorites & 1 Group

    GWT@Jazoon08 - Part 2/6 - Attentive Service - Presentation Transcript

        • # 2
        • attentive service.
    1. the doorman hailing a cab ...
    2. the waiter refilling your glass ...
    3. opening a new line at the checkout ...
        • annoying.
        • hit search button 10 times before match found
        • click add button for items that already exist
        • country dropdowns Belgium = b + 6x down arrow
        • intuitive.
        • act as a user not as a system
        • take all the nerdy and techy stuff out
        • user laziness is key
        • - auto complete
        • - smart tabs (members [0] vs members)
        • - smart country dropdown (your country on top)
        • gwt rpc.
        • [ for dummies ]
        • overview.
        • moves Java instances between client and server
        • uses Serializable + IsSerializable marker interface
        • polymorphism is supported but at a cost
        • generator creates the necessary marshaling code
        • supports Java 1.5 language constructs
        • built on top of RequestBuilder (XHR)
        • DEFINE REMOTE SERVICE
        • @RemoteServiceRelativePath(“wishlistService.do”) // moduleBaseURL + value
        • public interface WishlistService extends RemoteService {
        • List<Wish> findMatches(String query);
        • }
        • IMPLEMENT REMOTE SERVICE
        • public class WishlistServiceImpl extends RemoteServiceServlet
        • implements WishlistService {
        • public List<Wish> findMatches(String query) { ... do something ... }
        • }
        • DEFINE ASYNC SERVICE
        • public interface WishlistService Async {
        • void findMatches(String query, AsyncCallback async );
        • }
        • CALL SERVICE
        • WishlistAsyncServiceAsync service = GWT.create (WishlistService.class);
        • service.findMatches(“abc”, new AsyncCallback <List<Wish>>() {
        • public void onSuccess (List<Wish> matches) { ... }
        • public void onFailure (Throwable caught) { ... }
        • });
        • gwt rpc.
        • [ best practices ]
        • use stateless servers – better handling / scaling
        • keep conversational state on the client
        • balance your RPC calls, think about latency
        • only pull data that is really being used
        • paginate on the server
        • PROBLEM: NESTED INNER CALLBACK SYNDROME
        • // async call #1
        • myService. doFirstRequest (“foo”, new AsyncCallback<String>() {
        • public void onSuccess(String result) {
        • // async call #2
        • myService. doSecondRequest (result, new AsyncCallback<String>() {
        • public void onSuccess(String result) {
        • // and more and more and moreeee async calls on the way
        • }
        • public void onFailure(Throwable caught) { ... }
        • });
        • }
        • public void onFailure(Throwable caught) { ... }
        • });
        • BAD SOLUTION: NESTED CALLBACKS BECOME CLASSES
        • myService. doFirstRequest (“foo”, new FirstRequestHandler() );
        • class FirstRequestHandler implements AsyncCallback {
        • public void onSuccess(String result) {
        • myService. doSecondRequest (result, new SecondRequestHandler() );
        • public void onFailure(Throwable caught) { ... }
        • }
        • class SecondRequestHandler implements AsyncCallback {
        • }
        • SOLUTION: REFACTOR NESTED CALLBACKS INTO METHODS
        • myService. doFirstRequest (“foo”, handleFirstRequest() );
        • protected AsyncCallback handleFirstRequest() {
        • return new AsyncCallback<String>() {
        • public void onSuccess(String result) {
        • myService. doSecondRequest (result, handeSecondRequest() );}
        • public void onFailure(Throwable caught) { ... }
        • }
        • }
        • protected AsyncCallback handleSecondRequest() { … }
        • real world issues.
        • GWT + JPA = KABOOMMM !!!
        • back to the future with DTOs ???
        • SpringFramework integration ???
        • gwt rpc.
        • [ demystified ]
      • WishlistServiceAsync service = (...) GWT.create (WishlistService.class);
        • service.findMatches(“abc”, new AsyncCallback<List<Wish>>() {
        • public void onSuccess (List<Wish> matches) { ... }
        • public void onFailure (Throwable caught) { ... }
        • });
      WishlistServiceImpl extends RemoteServiceServlet ???
    4. RequestBuilder RemoteServiceProxy
      • WishlistServiceAsync service = (...) GWT.create (WishlistService.class);
        • service.findMatches(“abc”, new AsyncCallback<List<Wish>>() {
        • public void onSuccess (List<Wish> matches) { ... }
        • public void onFailure (Throwable caught) { ... }
        • });
      WishlistServiceImpl RemoteServiceServlet WishlistServiceAsync service
        • public void onSuccess(List<Wish> matches) { ... }
        • public void onFailure(Throwable caught) { ... }
      WishlistService_Proxy XHR RequestCallbackAdapter RemoteServiceProxy - configure RequestBuilder - method = POST - header = text/x-gwt-rpc - url - data - invoke RequestBuilder send() RemoteServiceServlet - invoke implementation - write response WishlistService_Proxy [Generated] WishlistService_Proxy [Generated] - prepare stream RequestCallbackAdapter RequestCallbackAdapter - trigger client callback for: - onError - onResponseReceived XHR - response found - trigger callback XHR XHR - make request - listen to response RequestBuilder - init XHR callback - open XHR - send data
        • WishlistService_Proxy.java [generated]
        • public class WishlistService_Proxy extends RemoteServiceProxy
        • implements WishlistServiceAsync {
        • public void findMatches (String text, AsyncCallback async) {
        • ...
        • ClientSerializationStreamWriter w = createStreamWriter(); // _TypeSerializer
        • w.writeString(“WishlistService”); // Remote service I/F name
        • w.writeString( &quot;findMatches&quot; ); // MethodName
        • w.writeInt(1); // Number of parameters
        • w.writeString(&quot;java.lang.String&quot;); // First parameter type
        • w.writeString( text ); // First parameter value
        • String payload = w.toString();
        • doInvoke(ResponseReader.OBJECT, “WishlistService_Proxy.findMatches&quot;,
        • getRequestId(), payload, async); }
        • }
        • RemoteServiceProxy.java
        • public abstract class RemoteServiceProxy implements ... {
        • protected <T> Request doInvoke (ResponseReader reader, String methodName,
        • int invocationCount, String requestData, AsyncCallback<T> async) {
        • RequestBuilder rb = new RequestBuilder( RequestBuilder.POST , “WishlistService.rpc” );
        • rb.setHeader(&quot;Content-Type&quot;, &quot;text/x-gwt-rpc; charset=utf-8&quot;);
        • rb.setCallback(responseHandler); // RequestCallbackAdapter
        • rb.setRequestData( requestData );
        • try {
        • rb. send();
        • } catch (RequestException re) {
        • callback.onFailure(new InvovationException(re))
        • }
        • }
        • RequestCallbackAdapter.java
        • public class RequestCallbackAdapter<T> implements RequestCallback {
        • public void onError (Request request, Throwable exception) {
        • callback.onFailure (exception);
        • }
        • public void onResponseReceived (Request request, Response response) {
        • String encodedResponse = response.getText();
        • int statusCode = response.getStatusCode();
        • if (statusCode != Response.SC_OK) { // + multiple other exception related test !!!
        • caught = new StatusCodeException(statusCode, encodedResponse);
        • } else {
        • result =
        • (T) responseReader.read(streamFactory.createStreamReader(encodedResponse));
        • }
        • if (caught == null) { callback.onSuccess (result); } else { callback.onFailure (caught);}
        • RemoteServiceServlet.java
        • public class RemoteServiceServlet extends HttpServlet implements ... {
        • public final void doPost (HttpServletRequest request, HttpServletResponse response) {
        • perThreadRequest.set(request);
        • perThreadResponse.set(response);
        • String requestPayload = RPCServletUtils.readContentAsUtf8(request);
        • RPCRequest rpcRequest = RPC. decodeRequest (requestPayload, …);
        • String responsePayload = RPC. invokeAndEncodeResponse (...);
        • //  calls remote method on WishListServiceImpl class
        • RPCServletUtils. writeResponse (..., responsePayload, ...);
        • gwt rpc.
        • [ rocked science ]
        • CUSTOMIZING RPC SERIALIZATION
        • PURPOSE
        • Null out lazy collections and load lazy proxy objects
        • EXAMPLE (subclass ServerSerializationStreamWriter)
        • public void serializableValue(Object value, Class type) ... {
        • else if (type == java.util.Set.class) {
        • Set hashSet = new HashSet();
        • if (value instanceof PersistentSet) {
        • PersistentSet persistentSet = (PersistentSet) value;
        • if (persistentSet.wasInitialized()) { hashSet.addAll(persistentSet);
        • gwt rpc.
        • [ new features ]
    5. ACCESSING THE REQUEST OBJECT
        • PURPOSE
        • useful for canceling the HTTP request used by RPC
        • EXAMPLE
        • public interface WishlistServiceAsync {
        • Request findMatches(String query, AsyncCallback async);
        • }
    6. ACCESSING THE REQUESTBUILDER OBJECT
        • PURPOSE
        • provides access to HTTP timeouts and headers
        • caller must manually call requestBuilder.send();
        • EXAMPLE
        • public interface WishlistServiceAsync {
        • RequestBuilder findMatches(String query, AsyncCallback async);
        • }
    7. INLINE PRESERIALIZED PAYLOADS (1/3)
        • PURPOSE
        • replace an RPC call that always takes place right after startup
        • one less call to make to the server (Turbo boost for startup)
    8. INLINE PRESERIALIZED PAYLOADS (2/3)
        • CREATE REMOTE SERVICE INTERFACE AS USUAL
        • public interface MyRemoteService extends RemoteService {
        • MyPayload aMethod(String var);
        • }
        • CREATE SERIALIZED VALUE ON THE SERVER-SIDE
        • String myPayload = RPC.encodeResponseForSuccess(…);
        • EMBED PAYLOAD INTO HTML PAGE (SiteMesh / Servlet / …)
        • <script>window.myPayload = “MyPayload generated String”</script>
    9. INLINE PRESERIALIZED PAYLOADS (3/3)
        • READ PRESERIALIZED STRING IN THE CLIENT
        • SerializationStreamFactory f = GWT.create(MyRemoteService.class);
        • MyPayload myPayload = f.createStreamReader(getPayload()).readObject();
        • native String getPayload() /*- {
        • return $wnd.myPayload;
        • } -*/
        • events.
        • ASYNC CALLBACK EVENTS
        • act upon success / failure of asynchronous callbacks
        • public interface AsyncCallback<T> {
        • void onFailure(Throwable caught);
        • void onSuccess(T result);
        • }
        • EVENT LISTENERS
        • listen upon events being triggered
        • implement EventListener
        • adapters available for some
        • don’t forget to detach the listeners when destroying the widget
        • examples
        • History.addHistoryListener(historyListener);
        • myButton.addClickListener(clickListener)
        • myTextField.addKeyboardListener(keyboardListenerAdapter)
        • NATIVE DOM EVENTS
        • public class MyWidget extends Widget {
        • public myWidget() {
        • setElement(DOM.createDiv());
        • sinkEvents(Event.ONCLICK()); // event bubbling
        • }
        • public void onBrowserEvent(Event event) {
        • switch (DOM.eventGetType(event)) {
        • case Event.ONCLICK: // do something…; break;
        • }
        • }
        • }
        • MEMORY LEAK
        • in some browsers any reference cycle that involves a JavaScript
        • object and a DOM element has a nasty tendency to never get
        • garbage-collected
        • hybrid system
        • DOM objects are referenced through reference counting
        • JS object is using garbage collection
        • example
        • obj = document.getElementById(&quot;DivElement&quot;);
        • document.getElementById(&quot;DivElement&quot;).propertyX = obj;
        • JS object “obj”  DOM object “DivElement”  obj / propertyX
        • MAARTENVOLDERS. com
        • PASSIONATE ABOUT PEOPLE AND TECHNOLOGY

    + Maarten VoldersMaarten Volders, 12 months ago

    custom

    1405 views, 2 favs, 0 embeds more stats

    A presentation about GWT which I presentaed at Jazo more

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 1405
      • 1405 on SlideShare
      • 0 from embeds
    • Comments 0
    • Favorites 2
    • Downloads 39
    Most viewed embeds

    more

    All embeds

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories

    Groups / Events