ChatGPT解决这个技术问题 Extra ChatGPT

Converting JSON data to Java object

I want to be able to access properties from a JSON string within my Java action method. The string is available by simply saying myJsonString = object.getJson(). Below is an example of what the string can look like:

{
    'title': 'ComputingandInformationsystems',
    'id': 1,
    'children': 'true',
    'groups': [{
        'title': 'LeveloneCIS',
        'id': 2,
        'children': 'true',
        'groups': [{
            'title': 'IntroToComputingandInternet',
            'id': 3,
            'children': 'false',
            'groups': []
        }]
    }]
}

In this string every JSON object contains an array of other JSON objects. The intention is to extract a list of IDs where any given object possessing a group property that contains other JSON objects. I looked at Google's Gson as a potential JSON plugin. Can anyone offer some form of guidance as to how I can generate Java from this JSON string?


C
Community

I looked at Google's Gson as a potential JSON plugin. Can anyone offer some form of guidance as to how I can generate Java from this JSON string?

Google Gson supports generics and nested beans. The [] in JSON represents an array and should map to a Java collection such as List or just a plain Java array. The {} in JSON represents an object and should map to a Java Map or just some JavaBean class.

You have a JSON object with several properties of which the groups property represents an array of nested objects of the very same type. This can be parsed with Gson the following way:

package com.stackoverflow.q1688099;

import java.util.List;
import com.google.gson.Gson;

public class Test {

    public static void main(String... args) throws Exception {
        String json = 
            "{"
                + "'title': 'Computing and Information systems',"
                + "'id' : 1,"
                + "'children' : 'true',"
                + "'groups' : [{"
                    + "'title' : 'Level one CIS',"
                    + "'id' : 2,"
                    + "'children' : 'true',"
                    + "'groups' : [{"
                        + "'title' : 'Intro To Computing and Internet',"
                        + "'id' : 3,"
                        + "'children': 'false',"
                        + "'groups':[]"
                    + "}]" 
                + "}]"
            + "}";

        // Now do the magic.
        Data data = new Gson().fromJson(json, Data.class);

        // Show it.
        System.out.println(data);
    }

}

class Data {
    private String title;
    private Long id;
    private Boolean children;
    private List<Data> groups;

    public String getTitle() { return title; }
    public Long getId() { return id; }
    public Boolean getChildren() { return children; }
    public List<Data> getGroups() { return groups; }

    public void setTitle(String title) { this.title = title; }
    public void setId(Long id) { this.id = id; }
    public void setChildren(Boolean children) { this.children = children; }
    public void setGroups(List<Data> groups) { this.groups = groups; }
    
    public String toString() {
        return String.format("title:%s,id:%d,children:%s,groups:%s", title, id, children, groups);
    }
}

Fairly simple, isn't it? Just have a suitable JavaBean and call Gson#fromJson().

See also:

Json.org - Introduction to JSON

Gson User Guide - Introduction to Gson


Performant? Have you actually measured it? While GSON has reasonable feature set, I thought performance was sort of weak spot (as per [cowtowncoder.com/blog/archives/2009/09/entry_326.html]) As to example: I thought GSON did not really need setters, and was based on fields. So code could be simplified slightly.
I use it in an android app. It is not the fastest possible solution but it is simple enough to program to justify the lack of performance for the user until now. Maybe in a later version of the app it will be removed for a faster solution.
Wrt speed, if it's fast enough, it's fast enough. I just commented on reference to expected good performance. Feature-set wise Jackson handles all the same nesting, layering, generics, so that's not where speed difference comes from. Having getters and setters does not impact performance in any measurable way (for packages I am aware of), so definitely can have them there.
+1 for the "package com.stackoverflow.q1688099;". For some reason it made me chuckle.
i have worked with java and json A LOT. Nothing comes close to Jackson, StaxMan is the DADDY!!!!, GSon is a nice try but it doesnt get the Cigar:)
D
Dave Jarvis

Bewaaaaare of Gson! It's very cool, very great, but the second you want to do anything other than simple objects, you could easily need to start building your own serializers (which isn't that hard).

Also, if you have an array of Objects, and you deserialize some json into that array of Objects, the true types are LOST! The full objects won't even be copied! Use XStream.. Which, if using the jsondriver and setting the proper settings, will encode ugly types into the actual json, so that you don't loose anything. A small price to pay (ugly json) for true serialization.

Note that Jackson fixes these issues, and is faster than GSON.


I've written a fork of Gson which fixes these issues (and avoids all the annotations of the Jackson): github.com/winterstein/flexi-gson
Y
Yogi Valani

Oddly, the only decent JSON processor mentioned so far has been GSON.

Here are more good choices:

Jackson (Github) -- powerful data binding (JSON to/from POJOs), streaming (ultra fast), tree model (convenient for untyped access)

Flex-JSON -- highly configurable serialization

EDIT (Aug/2013):

One more to consider:

Genson -- functionality similar to Jackson, aimed to be easier to configure by developer


D
Diego Sevilla

Or with Jackson:

String json = "...";
ObjectMapper m = new ObjectMapper();
Set<Product> products = m.readValue(json, new TypeReference<Set<Product>>() {});

This will give error can not deserialize instance of java.util.HashSet out of START_OBJECT token
R
Rahul Raina

Easy and working java code to convert JSONObject to Java Object

Employee.java

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Generated;

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
"id",
"firstName",
"lastName"
})
public class Employee {

@JsonProperty("id")
private Integer id;
@JsonProperty("firstName")
private String firstName;
@JsonProperty("lastName")
private String lastName;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();

/**
*
* @return
* The id
*/
@JsonProperty("id")
public Integer getId() {
return id;
}

/**
*
* @param id
* The id
*/
@JsonProperty("id")
public void setId(Integer id) {
this.id = id;
}

/**
*
* @return
* The firstName
*/
@JsonProperty("firstName")
public String getFirstName() {
return firstName;
}

/**
*
* @param firstName
* The firstName
*/
@JsonProperty("firstName")
public void setFirstName(String firstName) {
this.firstName = firstName;
}

/**
*
* @return
* The lastName
*/
@JsonProperty("lastName")
public String getLastName() {
return lastName;
}

/**
*
* @param lastName
* The lastName
*/
@JsonProperty("lastName")
public void setLastName(String lastName) {
this.lastName = lastName;
}

@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}

@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}

}

LoadFromJSON.java

import org.codehaus.jettison.json.JSONObject;

import com.fasterxml.jackson.databind.ObjectMapper;

public class LoadFromJSON {

    public static void main(String args[]) throws Exception {
        JSONObject json = new JSONObject();
        json.put("id", 2);
        json.put("firstName", "hello");
        json.put("lastName", "world");

        byte[] jsonData = json.toString().getBytes();

        ObjectMapper mapper = new ObjectMapper();
        Employee employee = mapper.readValue(jsonData, Employee.class);

        System.out.print(employee.getLastName());

    }
}

How to access these json properties in JSP?
If you wan't to use it in JSP page then code is still the same. The Employee.java class will be same as it is. But the Code written in LoadFromJSON.java will be copied in jsp page with the proper import of every class. Rest there is no change at all.
c
cherouvim

If, by any change, you are in an application which already uses http://restfb.com/ then you can do:

import com.restfb.json.JsonObject;

...

JsonObject json = new JsonObject(jsonString);
json.get("title");

etc.


your solution is shorter and more understandable, why it only receives 3 upvotes? Is there anything wrong?
M
Massimiliano Kraus
HashMap keyArrayList = new HashMap();
Iterator itr = yourJson.keys();
while (itr.hasNext())
{
    String key = (String) itr.next();
    keyArrayList.put(key, yourJson.get(key).toString());
}

J
Juanma

If you use any kind of special maps with keys or values also of special maps, you will find it's not contemplated by the implementation of google.


j
juanlumn

Depending on the input JSON format(string/file) create a jSONString. Sample Message class object corresponding to JSON can be obtained as below:

Message msgFromJSON = new ObjectMapper().readValue(jSONString, Message.class);

K
Kevin

What's wrong with the standard stuff?

JSONObject jsonObject = new JSONObject(someJsonString);
JSONArray jsonArray = jsonObject.getJSONArray("someJsonArray");
String value = jsonArray.optJSONObject(i).getString("someJsonValue");

it's terribly slow: github.com/fabienrenaud/java-json-benchmark recently at the job, i doubled the performance (cpu usage cut in half, latency cut in halt) of our prod servers by switching all org.json ser/deserialization calls to use jackson.
R
RickHigh

Give boon a try:

https://github.com/RichardHightower/boon

It is wicked fast:

https://github.com/RichardHightower/json-parsers-benchmark

Don't take my word for it... check out the gatling benchmark.

https://github.com/gatling/json-parsers-benchmark

(Up to 4x is some cases, and out of the 100s of test. It also has a index overlay mode that is even faster. It is young but already has some users.)

It can parse JSON to Maps and Lists faster than any other lib can parse to a JSON DOM and that is without Index Overlay mode. With Boon Index Overlay mode, it is even faster.

It also has a very fast JSON lax mode and a PLIST parser mode. :) (and has a super low memory, direct from bytes mode with UTF-8 encoding on the fly).

It also has the fastest JSON to JavaBean mode too.

It is new, but if speed and simple API is what you are looking for, I don't think there is a faster or more minimalist API.


can you provide a link for up to date documentation for the latest version? As of today, I found 0.4, but can't easily find a matching doc link or tutorial for that version. Thanks
Here is a tutorial github.com/RichardHightower/boon/wiki/Boon-JSON-in-five-minutes Boon is in the public maven repo. It is at 0.27 or so.
richardhightower.github.io/site/releases has 0.4, so I thought that was the latest. I've been checking out Boon for a project at work, does it have an equivalent annotation to Jackson's @JsonIgnore ?
boon is on the lower end of ser/deserialization performance: github.com/fabienrenaud/java-json-benchmark Choose jackson or dsljson for performance. @RickHigh: I couldn't open an issue on your github, i am more than willing to improve my benchmark or correct its interpretation if there is anything wrong/that-i-missed about it.
M
Massimiliano Kraus

The easiest way is that you can use this softconvertvalue method which is a custom method in which you can convert jsonData into your specific Dto class.

Dto response = softConvertValue(jsonData, Dto.class);


public static <T> T softConvertValue(Object fromValue, Class<T> toValueType) 
{
    ObjectMapper objMapper = new ObjectMapper();
    return objMapper
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        .convertValue(fromValue, toValueType);
}

S
Sathiamoorthy

Pass your JSON file in this way, it will return the object.

File file = new File("D:\\Coding\\tickets\\temp.json");
ObjectMapper om = new ObjectMapper();
Profile profile = om.readValue(file, new TypeReference<Profile>() {});

s
skyho

        <!-- GSON -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.7</version>
        </dependency>
  @Test
    void readListJsonFromFileTest() throws IOException {

        Type type = new TypeToken<List<SimplePojo>>(){}.getType();

        String fromJsonFile = readFromJsonFile("json/simplePojoJsonList.json");

        List<SimplePojo> pojoList = gson.fromJson(fromJsonFile, type);

        Assertions.assertNotNull(pojoList);
    }

    @Test
    void readJsonFromFileTest() throws IOException {

        Type type = new TypeToken<SimplePojo>(){}.getType();

        String fromJsonFile = readFromJsonFile("json/simplePojoJson.json");

        SimplePojo simplePojo = gson.fromJson(fromJsonFile, type);

        Assertions.assertNotNull(simplePojo);
    }

     String readFromJsonFile(String pathToJson) throws IOException {

        InputStream resource = new ClassPathResource(pathToJson).getInputStream();

        String json = StreamUtils.copyToString(resource, StandardCharsets.UTF_8);

        return json;
    }