0

I have list of json List<String> and each string have json like this {"id":"22","name":"Name","order":"1"} And I want to fetch it to list of input box then when I save it I I want to take all changing and convert them to JSON

@ManagedBean
@ViewScoped
public class LiveStreamController extends ProductController implements Serializable {

    private static final long serialVersionUID = 5037909267669512508L;
    private static final Logger LOGGER = LoggerFactory.getLogger(LiveStreamController.class);

    private LiveStream liveStream;

....
}

 public class LiveStream extends Product implements Serializable {
    private List<String> jsons = new ArrayList<>();
...
}

and I wanna read it

            <c:forEach items="#{liveStreamController.liveStream.jsons}"
                var="json ">
                <h:outputFormat value="#{json.name}" />
                <p:inputText value="#{json.order}" />
            </c:forEach>
Kukeltje
  • 12,223
  • 4
  • 24
  • 47
yali
  • 1,038
  • 4
  • 15
  • 31
  • Does this answer your question? [Decoding JSON String in Java](https://stackoverflow.com/questions/16574482/decoding-json-string-in-java) – Alexis Philip Apr 30 '20 at 17:29
  • you need json simple library for this. see @AlexisPhilip's comment – Shoshi Apr 30 '20 at 17:36
  • how can I handle it in the managed bean? – yali Apr 30 '20 at 17:39
  • Does this answer your question? [How to parse JSON in Java](https://stackoverflow.com/questions/2591098/how-to-parse-json-in-java) – Jasper de Vries Apr 30 '20 at 18:31
  • Although both 'Does this answer your question' references are telling you what is sort of needed (although the links does not reference the standards that currently exist for this if you order the answer on most votes), I created an answer on why your initial idea does not work and why conversion to more strongly typed objects is needed. – Kukeltje Apr 30 '20 at 19:16

2 Answers2

2

Effectively you are not asking a JSF question but an EL question since the #{json.name} expression is just that... Expression Language.

About the 'issue'...

If the value of the var="json" is a String, which it in your case is, it will be resolved by the basic resolvers that will for sure know about a String. An attempt will be made to call the property name on the string via a getName() which obviously does not exist, resulting in a Property 'name' not found on type java.lang.String. All of this is also explained in Property 'someproperty' not found on type java.lang.String. Therefor using it like in your example will not work

About the solution(s) for reading...

There are basically 3 solutions for reading the JSON and displaying it

New String EL Resolver
You could create a custom EL resolver and put it first in the order of resolvers so that for every string that needs to be resolved checks if it is effectively JSON (minimally parsing it) and if you think it IS JSON, then parse the JSON fully and read/interpret the EL and try to apply it to the JSON object. All this is going to be rather expensive as far as I can see (but BalusC might have a different idea)

New JSON EL Resolver
The second, a little better solution, is converting the String to a JSON object of you choice (there are many in Java, including a standardized one, 'JSON-P', since Java EE 7 and a newer version for Java EE 8). There is as far as I know no default included EL resolver that knows how to handle these in EL, but examples exist for the non standardized EL formats No idea how this would perform though, testing is knowing.

Existing EL Resolver
The third option is to convert the JSON to Normally strongly typed objects and then have the normal existing resolvers act on them. This can be Default existing java types like Map, List, String and other normal values, but it could even be more strongly typed like Person , Order, Converting JSON Strings to strongly typed object was a feature that existed in the non-standardized JSON libraries but not in default Java(EE) until Java EE 8, JSON-B. This has an additional advantage that code completion works and validations work in an IDE

About the solution(s) for writing...

Since you do seem to wanting to write results back to the JSON String (you have an input in your example), the first solution for reading is very hard to extend to writing, and if possible, it would totally break the advantage you seem to want to get of not writing code to be able to use this. The second and third solution both might work but the third has the advantage that input validations can be implemented, like bean validation and more.

Kukeltje
  • 12,223
  • 4
  • 24
  • 47
0

create a class:

public class JsonWrapper {

    JsonObject o;

    public JsonWrapper(String s) {
        this(new JsonParser().parse(s).getAsJsonObject());
    }

    public JsonWrapper(JsonObject o) {
        this.o = o;
    }

    public String getJsonText() {
        return o.getAsString();
    }

    public DataWrapper get(String field) {
        return new DataWrapper(field);
    }


    public class DataWrapper {

        String field;

        public DataWrapper() {
        }

        public DataWrapper(String field) {
            this.field = field;
        }

        public String getData() {
            return o.get(field).getAsString();
        }

        public void setData(String s) {
            o.add(field, new JsonPrimitive(s));
        }
    }

}

convert your live stream to object like this:

List<JsonWrapper> jwList = s.stream().map(s1 -> new JsonWrapper(s1)).collect(Collectors.toList());
setter & getter

Use it in xhtml

<c:forEach items="#{liveStreamController.liveStream.jwList}" var="jw">
   <h:outputFormat value="#{jw.get('name').data}" />
   <p:inputText value="#{jw.get('order').data}" />
</c:forEach>

Use modified data with:

List<String> jsonList = jw.stream().map(JsonWrapper::getJsonText).collect(Collectors.toList());
utrucceh
  • 1,076
  • 6
  • 11
  • JsonObject and JsonParser are from? And how does this work with date fields? Booleans? etc? – Kukeltje May 01 '20 at 09:51
  • For `DataWrapper` modify set get type from `String` to `Object` and in `setData` handle casting with type checkings – utrucceh May 01 '20 at 09:58
  • Ok, but Isn't it better than to create really strongly typed object and have the json library bind them? That brings me to the first part of my comment... Java-EE7/8 ? – Kukeltje May 01 '20 at 11:39
  • This is a small tool, if you really need strong typed object, you can convert json text to `Product` class and use it with xhtml. `JsonObject` and `JsonParser` from `Gson` library. – utrucceh May 01 '20 at 19:33