" I also solved the problem of List and Map with an own Interface, which is
an ArrayList/HashMap on serverside and an own implemented native List/Map
on gwt side" can you share the solution ?
Il giorno venerdì 29 settembre 2017 alle 14:00:12 UTC+2 Ignacio Baca
Moreno-Torres ha scritto:
> We have been using this technique for more than a year and it works
> perfectly. We call it "Java Notation Object", hehe and you should
> understand the limitations, which more or less you are currently
> fulfilling. Just a few changes...
>
> The most important, yes, you should use
> @JsType(isNative=true,namespace=GLOBAL,name="Object"), so you are actually
> ignoring any kind of typing, so this is more a "scheme" of where to find
> things than an actual typed object. This is pretty important! This is
> pretty similar to JSON but in Java, and these classes are not actually Java
> classes, are just a scheme. All these limitations are the common
> intersection of the feature between Java and JS.
>
> You can do some tricks to use collections but we end up removing all of
> them and using arrays instead. But, to make it easy to work with, we added
> some @JsOverlay to return or set the Collection. For example if you have
> "String[] roles" you can add "@JsOverlay getRoleSet() { return
> Stream.of(roles).collecto(toSet()); }". Overlays are ok bc there are just
> like extension method or static method, so no behavior is added to the
> object.
>
> This work perfectly on both sides, but there is a small annoying
> difference between GWT and Java, in java new Foo() will initialize
> primitive types and in GWT (js) will not. So we never use constructor
> directly, in the kind of classes we always add a static factory method and
> we initialize any non-nullable field, even primitives! So in java you are
> actually creating the object of the specified type, but in JS you are just
> calling "new Object()", but it is ok, bc where are using a scheme, no a
> type. And we never use instanceof on these schemes! This will work on the
> Java side, but I strongly discourage, you should not need to do that.
>
> Finally, we never use getter and setter, don't make sense, you "cannot use
> inheritance" (you can use with some ticks too, for example using some int
> or string field as the type indicator and using, for example, the visitor
> pattern to traverse, this is what actually people need to do in JS so, no
> magic just the common intersection of features between java and json),
> almost everything is like final and you must not add behavior, so it is
> much explicit and easier to just make all field public.
>
> I think the first you should do is removing getters and setters, and add
> @JsType(native,Object) to all your types, this refactor can be done almost
> instantly in your IDE (inline method). Then stop using Collection might not
> be so easy to refactor. So you might continue using it either using
> overlays or creating a custom jsinterop-compatible type. In this case, I
> recommend to not to use the whole java.util API bc it will force you to
> export the whole API and use generateJsInteropExports. If you are really
> interested or need help there just ask, but just try out avoiding maps, and
> using arrays. Anyways, the "Map/List own interface" should work too, just
> neet to make it work.
>
> On Fri, Sep 29, 2017 at 12:53 PM Thomas Broyer <[email protected]> wrote:
>
>>
>>
>> On Friday, September 29, 2017 at 11:09:42 AM UTC+2, Jürgen Beringer wrote:
>>>
>>> Hey,
>>>
>>> currently I tried the 2. time to move our application from gwt 2.7 to
>>> gwt 2.8, but I have big problems with the changes of JsInterop.
>>>
>>> The application contains a serverside java part, running in a jetty and
>>> the client part, build with gwt, so I can reuse many software on server and
>>> client side. (It is the main part of the website www.spreadshirt.com )
>>> To use also the same data classes (containing only fields with getter
>>> and setter, no other methods) on both sides, I used JsInterop and it works
>>> very well with gwt 2.7 and exchanged the data as json.
>>>
>>> Example Data class:
>>>
>>> @JsType
>>> public class MyObject {
>>> private String id;
>>>
>>> @JsProperty
>>> public String getId() {
>>> return id;
>>> }
>>> @JsProperty
>>> public void setId(String id) {
>>> this.id = id;
>>> }
>>> }
>>>
>>>
>>> The class can be used on server side like any normal java class with any
>>> REST Framework. On gwt side I was able to convert a transmitted json to the
>>> class with:
>>>
>>>
>>> MyObject myObject = getJsTypeObject(JsonUtils.safeEval(jsonString));
>>> //use getter and setter to access fields
>>>
>>> public static native <T> T getJsTypeObject(JavaScriptObject result)/*-{
>>> return result;
>>> }-*/;
>>>
>>>
>>> And to create Objects on gwt side and send them to the server as json:
>>>
>>> MyObject myObject = new MyObject();
>>> myObject.setId("1");
>>> String jsonString = stringify(myObject);
>>>
>>>
>>> public static final native String stringify(Object result) /*-{
>>> return JSON.stringify(result);
>>> }-*/;
>>>
>>>
>>> I also solved the problem of List and Map with an own Interface, which
>>> is an ArrayList/HashMap on serverside and an own implemented native
>>> List/Map on gwt side.
>>>
>>> The application has more than 100 such Objects which are heavily used on
>>> server and client side in many methods which are also be used on both
>>> sides. So implementing them twice for server and client side would be a big
>>> overhead.
>>> Now is my question, how can I convert this gwt 2.7 code to gwt 2.8
>>> (mainly to be able to use Java8 syntax in future). I tried multiple
>>> variants, but it seems for me, JsInterop in gwt 2.8 is not planned for such
>>> usecases which were possible in gwt 2.7 withou any problems.
>>> I can either use a native Javascript Object in gwt (native=true) or a in
>>> GWT created Object in Javascript. But I see no solution to do both with the
>>> same Type.
>>>
>>> I get 2 Problems
>>>
>>> - Casting issues: I can't use native=true because I also want to
>>> create such Objects on gwt side, so on every assignment (jsonString to
>>> typed variable) I get a cast exception and at least in superdev mode I
>>> can't deactivate the cast exceptions
>>>
>>> If you never do "instanceof" (or expect cast exceptions) on client-side,
>> you could probably use isNative=true,namespace=GLOBAL,name="Object"; that
>> way, all your objects are plain old JS objects (no specific
>> class/constructor is generated in JS), which is actually exactly what you'd
>> expect from JSON.parse().
>>
>>>
>>> - field name problems: The jsonString of the last example is
>>> {"id_g_$3":"1"} and not {"id":"1"} because the JsProperty for getter and
>>> setter works only fine with native objects. If I add JsProperty to the
>>> field itself, I can't do have JsProperty for the getter and setter, so I
>>> have to add JsIgnore to them. But then when I work with native Objects I
>>> can't use the getter and setter on gwt side. I would need JsProperty on
>>> getter, setter and the field itself, but this is also not allowed.
>>>
>>>
>> The "id_g_$3" is probably because you don't -generateJsInteropExports;
>> contrary to 2.7, in 2.8, the "don't obfuscate @JsProperty/@JsMethod names"
>> only applies when you -generateJsInteropExports.
>> But if you switch to isNative=true,namespace=GLOBAL,name="Object", you
>> don't even need it.
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "GWT Users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> To post to this group, send email to [email protected].
>> Visit this group at https://groups.google.com/group/google-web-toolkit.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
--
You received this message because you are subscribed to the Google Groups "GWT
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/google-web-toolkit/86e08739-184f-45fa-82e1-0c9965f65e2en%40googlegroups.com.