JSON - When to use JSONParser and when JavaScript object

25 views
Skip to first unread message

Raziel

unread,
Nov 12, 2009, 11:48:09 AM11/12/09
to Google Web Toolkit
I know this depends on the details of what you're trying to achieve
and the JSON object to be parsed (for example if it's dynamic
orstatic, etc).

I'm just wondering what are the principles that others follow to
determine when to use one or the other.

Thomas Broyer

unread,
Nov 12, 2009, 2:45:12 PM11/12/09
to Google Web Toolkit
I just do not ever use JSONParser, only JSOs (and with the JsonUtils
in GWT 2.0 you don't even need to do the eval() yourself). I sometimes
use the same JSO while the server sends me different JSON (with some
properties missing in some cases and not in others), I just write my
JSO to take this into account; for instance:

public final native int getIntProp() /*-{
return this.intProp !== null ? this.intProp : -1; // default
value; use this.intProp || 0 if the default value coerce to false
}-*/;

And actually, now that I've switched to GWT 2.0, I use interfaces to
model my objects, with RemoteService/*Async interfaces to model my
services; and I implement them using JSOs (JSOs can implement
interfaces under certain conditions in GWT 2.0) and RequestBuilder
(everything's injected using GIN so other classes don't matter whether
they use real RPC or a RequestBuilder-based RESTful service request)

Jeff Chimene

unread,
Nov 27, 2009, 10:56:22 AM11/27/09
to google-we...@googlegroups.com
On 11/12/2009 12:45 PM, Thomas Broyer wrote:
>
> On 12 nov, 17:48, Raziel<raziel...@gmail.com> wrote:
>> I know this depends on the details of what you're trying to achieve
>> and the JSON object to be parsed (for example if it's dynamic
>> orstatic, etc).
>>
>> I'm just wondering what are the principles that others follow to
>> determine when to use one or the other.
>
> I just do not ever use JSONParser, only JSOs (and with the JsonUtils
> in GWT 2.0 you don't even need to do the eval() yourself). I sometimes
> use the same JSO while the server sends me different JSON (with some
> properties missing in some cases and not in others), I just write my
> JSO to take this into account; for instance:
>
> public final native int getIntProp() /*-{
> return this.intProp !== null ? this.intProp : -1; // default
> value; use this.intProp || 0 if the default value coerce to false
> }-*/;
>
> And actually, now that I've switched to GWT 2.0, I use interfaces to
> model my objects, with RemoteService/*Async interfaces to model my
> services; and I implement them using JSOs (JSOs can implement
> interfaces under certain conditions in GWT 2.0)

Hi Thomas,

Would you mind expanding on this a little bit? How does one implement a
JSO interface?

Thomas Broyer

unread,
Nov 27, 2009, 4:30:30 PM11/27/09
to Google Web Toolkit
interface MyModelObject {
String getFoo();
void setFoo(String foo);
}

class MyModelObjectImpl extends JavaScriptObject implements
MyModelObject {
protected MyModelObjectImpl() { }
public final native String getFoo() /*-{ return this.foo; }-*/;
public final native void setFoo(String foo) /*-{ this.foo = foo; }-
*/;
}

There's really nothing special, but the interface cannot be
implemented by more than one JSO.

I then do:
interface MyService extends RemoteService {
MyModelObject get();
}
@ImplementedBy(MyServiceAsyncImpl.class)
interface MyServiceAsync {
void get(AsyncCallback<MyModelObject> callback);
}

implemented as:
class MyServiceAsyncImpl implements MyServiceAsync {
public void get(AsyncCallback<MyModelObject> callback) {
// create a RequestBuilder, and in the
RequestCallback::onResponceReceived, parse the response
(JsonUtils.unsafeEval for instance) into a MyModelObjectImpl and pass
it to the callback.onSuccess()
}
}

Jeff Chimene

unread,
Nov 28, 2009, 10:09:55 AM11/28/09
to google-we...@googlegroups.com
Thanks, very nice. I'll give it a try.

  }
}

--

You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.



Jeff Chimene

unread,
Dec 2, 2009, 5:52:02 PM12/2/09
to google-we...@googlegroups.com
Hi Thomas,

I had stumbled upon this solution. However, you have an additional detail I don't understand: The split between
interface MyModelObject 
and
class MyModelObjectImpl extends JavaScriptObject implements MyModelObject

What advantage does this gain? I think it has something to do w/. DI or testing, but I cannot see why one wouldn't do
void get(AsyncCallback<MyModelObjectImpl> callback);

i.e. don't use an interface, just do all templating via the class? Also, I see you're using @ImplementedBy. How does this differ from
bind(new TypeLiteral<SessionReaderTxn<Session>>() {}).to(MockSessionReader.class);

There is a redundancy in the above that I haven't figured out how to factor out. Ideally, it should be either
bind(new TypeLiteral<ReaderTxn<Session>>() {}).to(MockSessionReader.class);
or
bind(new TypeLiteral<SessionTxn<Reader>>() {}).to(MockSessionReader.class);

Cheers,
jec

On Fri, Nov 27, 2009 at 2:30 PM, Thomas Broyer <t.br...@gmail.com> wrote:

Thomas Broyer

unread,
Dec 2, 2009, 6:48:46 PM12/2/09
to Google Web Toolkit


On 2 déc, 23:52, Jeff Chimene <jchim...@gmail.com> wrote:
> Hi Thomas,
>
> I had stumbled upon this solution. However, you have an additional detail I
> don't understand: The split between
> interface MyModelObject
> and
> class MyModelObjectImpl extends JavaScriptObject implements MyModelObject
>
> What advantage does this gain? I think it has something to do w/. DI or
> testing, but I cannot see why one wouldn't do
> void get(AsyncCallback<MyModelObjectImpl> callback);
>
> i.e. don't use an interface, just do all templating via the class?

If I'd do this, then I'd be breaking the assumption that my RPC
interface could be implemented as a "real" GWT-RPC, because I'd be
exposing an "implementation detail" (MyModelObjectImpl extends
JavaScriptObject, which means it cannot be used on the server side, so
this cannot be GWT-RPC but only an attempt at making something looking
like GWT-RPC).

The idea is that if I want to use GWT-RPC instead of my own
implementation, it won't break the code using the service.

> Also, I
> see you're using @ImplementedBy. How does this differ from
> bind(new TypeLiteral<SessionReaderTxn<Session>>()
> {}).to(MockSessionReader.class);

It's equivalent to bind(MyServiceAsync.class).to
(MyServiceAsyncImpl.class) *except* that:
- because it's not explicit it's a "by default" binding (aka "JIT
binding"), which means that:
- it doesn't require a GIN module (my app is composed of several
GWT modules, so I'd have my application-level GIN module –injector
actually– to inherit the GIN modules of all inherited GWT module)
- it can be "overridden" by an explicit binding in a GIN module (we
build "sample" apps to allow manual testing of the whole MVP –
including the real view that'll be used in the app–, with sample
service implementations that don't do any network call but instead
return sample data that ideally cover all special cases that we could
find "in the real" later; without the need to have the data in a
database)
- it's easier to maintain than an explicit binding in a GIN
module ;-)

> There is a redundancy in the above that I haven't figured out how to factor
> out. Ideally, it should be either
> bind(new TypeLiteral<ReaderTxn<Session>>() {}).to(MockSessionReader.class);
> or
> bind(new TypeLiteral<SessionTxn<Reader>>() {}).to(MockSessionReader.class);

I'm sorry, I don't understand: what are "reader" and "session" here?
why is this using TypeLiteral?

The @ImplementedBy is on the MyServiceAsync interface, not the
AsyncCallback. The AsyncCallback is never injected by DI, I cannot see
a use case for it (would you DI your event handlers?), it's generally
implemented as an anonymous nested class, which also means it's
explicitly instantiated where it's defined, i.e. in the presenters.

Jeff Chimene

unread,
Dec 2, 2009, 9:26:09 PM12/2/09
to google-we...@googlegroups.com
On Wed, Dec 2, 2009 at 4:48 PM, Thomas Broyer <t.br...@gmail.com> wrote:


On 2 déc, 23:52, Jeff Chimene <jchim...@gmail.com> wrote:
> Hi Thomas,
>
> I had stumbled upon this solution. However, you have an additional detail I
> don't understand: The split between
> interface MyModelObject
> and
> class MyModelObjectImpl extends JavaScriptObject implements MyModelObject
>
> What advantage does this gain? I think it has something to do w/. DI or
> testing, but I cannot see why one wouldn't do
> void get(AsyncCallback<MyModelObjectImpl> callback);
>
> i.e. don't use an interface, just do all templating via the class?

If I'd do this, then I'd be breaking the assumption that my RPC
interface could be implemented as a "real" GWT-RPC, because I'd be
exposing an "implementation detail" (MyModelObjectImpl extends
JavaScriptObject, which means it cannot be used on the server side, so
this cannot be GWT-RPC but only an attempt at making something looking
like GWT-RPC).

The idea is that if I want to use GWT-RPC instead of my own
implementation, it won't break the code using the service.

OK. I keep forgetting about Java RPC.
 

> Also, I
> see you're using @ImplementedBy. How does this differ from
> bind(new TypeLiteral<SessionReaderTxn<Session>>()
> {}).to(MockSessionReader.class);

It's equivalent to bind(MyServiceAsync.class).to
(MyServiceAsyncImpl.class) *except* that:
 - because it's not explicit it's a "by default" binding  (aka "JIT
binding"), which means that:
  - it doesn't require a GIN module (my app is composed of several
GWT modules, so I'd have my application-level GIN module –injector
actually– to inherit the GIN modules of all inherited GWT module)
  - it can be "overridden" by an explicit binding in a GIN module (we
build "sample" apps to allow manual testing of the whole MVP –
including the real view that'll be used in the app–, with sample
service implementations that don't do any network call but instead
return sample data that ideally cover all special cases that we could
find "in the real" later; without the need to have the data in a
database)
 - it's easier to maintain than an explicit binding in a GIN
module ;-)

OK, I think I get that line of reasoning. I've committed to two GIN modules. However, I do like the JIT binding aspect.
 

> There is a redundancy in the above that I haven't figured out how to factor
> out. Ideally, it should be either
> bind(new TypeLiteral<ReaderTxn<Session>>() {}).to(MockSessionReader.class);
> or
> bind(new TypeLiteral<SessionTxn<Reader>>() {}).to(MockSessionReader.class);

I'm sorry, I don't understand: what are "reader" and "session" here?
why is this using TypeLiteral?

The goal with TypeLiteral is to "color" an interface so that I can have one interface describing all HTTP GET requests (ReaderTxn), and another interface describing all HTTP PUT requests (WriterTxn). The "color" should give GIN the information it needs to bind the implementation based on the data type (aka "color")


bind(new TypeLiteral<ReaderTxn<Session>>() {}).to(MockSessionReader.class);
bind(new TypeLiteral<ReaderTxn<Authorization>>() {}).to(MockAuthorizationReader.class);

I tried something like

public interface ReaderTxn<?> {
   public get<Session> (String sessionId);

  public get<Authorization> (String username, String password);
}

But, as you know, the Session handler must implement the Authorization get() and vice versa.

So now I just bury each of the above get() methods  in an implementation of the data-type specific interface. An extension of the abstract Transaction class handles the rest of the HTTP machinery:

public class AuthenticateReader extends Transaction implements AuthenticateReaderTxn

This is probably clear as mud.

Anyway, I'm back to SessionReaderTxn and AuthorizationReaderTxn, i.e. hard-coding the data type in the class name. The Type Literal is a holdover from an earlier attempt to have a one routine handle multiple types.

The @ImplementedBy is on the MyServiceAsync interface, not the
AsyncCallback. The AsyncCallback is never injected by DI, I cannot see
a use case for it (would you DI your event handlers?), it's generally
implemented as an anonymous nested class, which also means it's
explicitly instantiated where it's defined, i.e. in the presenters.

I see what you're doing (in the hazy sense of recognizing an image rippling in a fun-house mirror).  I'll have to try this with one of the members of the "model" package

Reply all
Reply to author
Forward
0 new messages