0

I'm new to Java and have used the long piece of code provided in

GWT: Dealing with incoming JSON string

to read the json similar to the layout of the original posting person raised.

My layout is as follows:

{
    "messagedata": [
        {
            "msgkey": "12552",
            "reference": "201708010001",
            "bic": "PARABLULLEISI",
            "securityid": "BE0003735496",
            "safekeepingacc": "7744085P"
        },
        {
            "msgkey": "12553",
            "reference": "000081676368",
            "bic": "PARABLULLEISX",
            "securityid": "CNE00000BQ0",
            "safekeepingacc": "1053542760H"
        }

    ]
}

But the final line of code (jsonString.stringValue()) only ever reads the first block of JSON data i.e. msgkey or bic from the first section.

How would i get data from other sections i.e. if there were 3 sections each containing msgkey, bic, reference etc

More importantly if i know the msgkey value as in the sample JSON how can I get the other associated values for that section when the msgkey value changes?

I've used the library com.google.gwt.json.client.*

Thanks Martin

2 Answers2

1

You can use JsInterop and JSON.parse in GWT 2.8 + elemental2.

import com.google.gwt.core.client.EntryPoint;
import elemental2.core.Global;
import elemental2.dom.DomGlobal;
import java.util.stream.Stream;
import jsinterop.annotations.*;
import jsinterop.base.Js;

class JsInteropExample implements EntryPoint {
    @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
    static class Message {
        public Data[] messagedata;
    }

    @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
    static class Data {
        public String msgkey;
        public String reference;
        public String bic;
        public String securityid;
        public String safekeepingacc;
    }

    @Override public void onModuleLoad() {
        Message msg = Js.cast(Global.JSON.parse("{\"messagedata\": […]}"));
        Stream.of(msg.messagedata).forEach(d -> DomGlobal.console.log(d.msgkey));
    }
}
Ignacio Baca
  • 1,538
  • 14
  • 18
  • Thanks for the reply but I'm having problems with IntelliJ where I tried to add json.simple & org.json libraries via mawen and i couldn't get the project to compile as it appears to ignore that these libraries were added. Pom.xml had dependency XML added manualy as well to no avail. – Martin Teefy Oct 26 '17 at 06:25
  • So having to add jsinterop and elemental2 would not work for me at present. The only reason I started using gwt json was the problem with simple json or org.json compilation issues. So I now have a form building the json via gwt.json and another form reading the json but i need to read the fields via another method that doesn't involve adding libraries. Any ideas? – Martin Teefy Oct 26 '17 at 06:29
  • I also tried the building of the json layout to have the fields as array sub-elements if that makes the accessing of bic or securityid via the msgkey any easier? – Martin Teefy Oct 26 '17 at 06:31
  • Not sure what you means, but if you upload a sample project to github I'll try to help with a PR which is much easier. Also, if you are trying to learn gwt it is better that you start with client only application, although all in gwt is about sharing code at first might be a bit confusing. – Ignacio Baca Oct 26 '17 at 18:28
1

I totally agree with Ignacio, JsInterop is the way, that is why I was asking about GWT version.

JsInterop will automatically map getter and setter to the right property as you can see below.

It also allow you to add java overlay methods to your native objects, which I personally find very convenient and clean.

In order to have this code working you need to make sure to have elemental2 and jsinterop imported in your gwt.xml files.

import com.google.gwt.core.client.EntryPoint;
import elemental2.core.Global;
import elemental2.dom.DomGlobal;
import java.util.stream.Stream;
import jsinterop.annotations.*;
import jsinterop.base.Js;

class JsInteropExample implements EntryPoint {
    @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
    static abstract class Message {

        @JsProperty
        public abstract Data[] getMessagedata();

        @JsOverlay
        public void logObject(){
            Stream.of(getMessagedata).forEach(d -> DomGlobal.console.log(d.msgkey));
        }
    }

    @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
    static class Data {
        public String msgkey;
        public String reference;
        public String bic;
        public String securityid;
        public String safekeepingacc;
    }

    @Override public void onModuleLoad() {
        Message msg = Js.cast(Global.JSON.parse("{\"messagedata\": […]}"));
        Stream.of(msg.messagedata).forEach(d -> DomGlobal.console.log(d.msgkey));
    }
}

If you want to avoid using elemental2 you can decode the Json by using:

@JsMethod(namespace="JSON")
static native DivData parse(String json);
Thomas Broyer
  • 64,353
  • 7
  • 91
  • 164
Luigi Polvani
  • 405
  • 5
  • 9
  • Ok, it appears my compilation error 'no source code is available for type org.json.JSONArray; did you forget to inherit a required module' maybe because org.josn is not supported by gwt? I've only been coding Java for a month( new project) after years of Vb/.Net, could you help me by writing a noddy sample project that includes the library you mentioned? – Martin Teefy Oct 26 '17 at 11:09
  • Don't use org.json, that does not translate into client code. In order to have this bit of code working you will need to add few lines to your .gwt.xml (elemental2 and jsinterop). Also you may need to throw elemental2 into your maven file. – Luigi Polvani Oct 26 '17 at 15:42
  • Thomas, thank you for killing that bit of JSNI, I am going to bring your snippet right into my product code. – Luigi Polvani Oct 26 '17 at 19:44