Chuyển đổi dữ liệu JSON thành đối tượng Java


262

Tôi muốn có thể truy cập các thuộc tính từ một chuỗi JSON trong phương thức hành động Java của tôi. Chuỗi có sẵn bằng cách nói đơn giản myJsonString = object.getJson(). Dưới đây là một ví dụ về chuỗi có thể trông như thế nào:

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

Trong chuỗi này, mọi đối tượng JSON chứa một mảng các đối tượng JSON khác. Mục đích là để trích xuất một danh sách các ID trong đó bất kỳ đối tượng cụ thể nào sở hữu thuộc tính nhóm có chứa các đối tượng JSON khác. Tôi đã xem Google Gson như một plugin JSON tiềm năng. Bất cứ ai cũng có thể cung cấp một số hình thức hướng dẫn về cách tôi có thể tạo Java từ chuỗi JSON này không?



Dưới đây là một ví dụ thegeekyland.blogspot.com/2015/11/ Quảng cáo
Arlind

Câu trả lời:


329

Tôi đã xem Google Gson như một plugin JSON tiềm năng. Bất cứ ai cũng có thể cung cấp một số hình thức hướng dẫn về cách tôi có thể tạo Java từ chuỗi JSON này không?

Google Gson hỗ trợ thuốc generic và đậu lồng nhau. Trong []JSON biểu thị một mảng và nên ánh xạ tới một bộ sưu tập Java, chẳng hạn như Listhoặc chỉ là một mảng Java đơn giản. Các {}trong JSON đại diện cho một đối tượng và phải ứng với một Java Maphay chỉ một số lớp JavaBean.

Bạn có một đối tượng JSON với một số thuộc tính trong đó thuộc groupstính đại diện cho một mảng các đối tượng lồng nhau cùng loại. Điều này có thể được phân tích cú pháp với Gson theo cách sau:

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);
    }
}

Khá đơn giản phải không? Chỉ cần có một JavaBean phù hợp và gọi Gson#fromJson().

Xem thêm:


4
Biểu diễn? Bạn đã thực sự đo nó? Mặc dù GSON có bộ tính năng hợp lý, tôi nghĩ rằng hiệu suất là một điểm yếu (theo [ cowtowncoder.com/blog/archives/2009/09/entry_326.html] ) Ví dụ: Tôi nghĩ rằng GSON không thực sự cần setters và được dựa trên các lĩnh vực. Vì vậy, mã có thể được đơn giản hóa một chút.
StaxMan

3
Tôi sử dụng nó trong một ứng dụng Android. Nó không phải là giải pháp nhanh nhất có thể nhưng nó đủ đơn giản để lập trình để biện minh cho việc thiếu hiệu năng cho người dùng cho đến bây giờ. Có thể trong phiên bản mới hơn của ứng dụng, nó sẽ bị xóa để có giải pháp nhanh hơn.
Janusz

1
Tốc độ Wrt, nếu nó đủ nhanh, nó đủ nhanh. Tôi chỉ nhận xét về tham chiếu để mong đợi hiệu suất tốt. Jackson khôn ngoan thiết lập tính năng xử lý tất cả các lồng ghép, xếp lớp, chung chung, vì vậy đó không phải là sự khác biệt về tốc độ. Có getters và setters không ảnh hưởng đến hiệu suất theo bất kỳ cách nào có thể đo lường được (đối với các gói tôi biết), vì vậy chắc chắn có thể có chúng ở đó.
StaxMan

97
+1 cho "gói com.stackoverflow.q1688099;". Vì một số lý do, nó làm tôi cười thầm.
GargantuChet

1
chuỗi công khai toString () {trả về Gson mới (). toJson (này); // Sử dụng cái này thay vì viết từng biến}
Prakash

45

Bewaaaaare của Gson! Nó rất mát, rất tuyệt vời, nhưng thứ hai bạn muốn làm bất cứ điều gì khác hơn là đối tượng đơn giản, bạn có thể dễ dàng cần phải bắt đầu xây dựng serializers của riêng bạn (mà không phải là cứng).

Ngoài ra, nếu bạn có một mảng các Đối tượng và bạn giải tuần tự hóa một số json vào mảng Đối tượng đó, các kiểu thực sự là MẤT! Các đối tượng đầy đủ thậm chí sẽ không được sao chép! Sử dụng XStream .. Mà, nếu sử dụng jsondriver và cài đặt các cài đặt phù hợp, sẽ mã hóa các loại xấu xí thành json thực tế, để bạn không mất bất cứ thứ gì. Một cái giá nhỏ phải trả (json xấu xí) cho việc xê-ri hóa thực sự.

Lưu ý rằng Jackson khắc phục các sự cố này và nhanh hơn GSON.


2
Tôi đã viết một ngã ba Gson để khắc phục những vấn đề này (và tránh tất cả các chú thích của Jackson): github.com/winterstein/flexi-gson
Daniel Winterstein

26

Điều kỳ lạ là bộ xử lý JSON tốt duy nhất được đề cập cho đến nay là GSON.

Dưới đây là nhiều lựa chọn tốt hơn:

  • Jackson ( Github ) - liên kết dữ liệu mạnh mẽ (JSON đến / từ POJOs), phát trực tuyến (cực nhanh), mô hình cây (thuận tiện cho truy cập không được kiểm tra)
  • Flex-JSON - tuần tự hóa cấu hình cao

EDIT (tháng 8 năm 2013):

Thêm một điều cần xem xét:

  • Genson - chức năng tương tự Jackson, nhằm mục đích dễ dàng cấu hình hơn bởi nhà phát triển

15

Hoặc với Jackson:

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

Điều này sẽ đưa ra lỗi không thể giải nén phiên bản java.util.Hashset ra khỏi mã thông báo
START_OB DỰ ÁN

7

Nếu, bằng bất kỳ thay đổi nào, bạn đang ở trong một ứng dụng đã sử dụng http://restfb.com/ thì bạn có thể làm:

import com.restfb.json.JsonObject;

...

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

Vân vân.


Giải pháp của bạn ngắn hơn và dễ hiểu hơn, tại sao nó chỉ nhận được 3 lượt upvote? Có gì sai không?
Jeff

4

Mã java dễ dàng và hoạt động để chuyển đổi JSONObjectsangJava 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);
}

}

TảiFromJSON.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());

    }
}

Làm thế nào để truy cập các thuộc tính json này trong JSP?
Zoran777

Nếu bạn không sử dụng nó trong trang JSP thì mã vẫn như vậy. Lớp Employee.java sẽ giống như vậy. Nhưng Mã được viết bằng LoadFromJSON.java sẽ được sao chép trong trang jsp với việc nhập đúng mỗi lớp. Nghỉ ngơi không có thay đổi gì cả.
Rahul Raina

4
HashMap keyArrayList = new HashMap();
Iterator itr = yourJson.keys();
while (itr.hasNext())
{
    String key = (String) itr.next();
    keyArrayList.put(key, yourJson.get(key).toString());
}

3

Nếu bạn sử dụng bất kỳ loại bản đồ đặc biệt nào có khóa hoặc giá trị của bản đồ đặc biệt, bạn sẽ thấy nó không được dự tính bởi việc triển khai google.


2

Có gì sai với những thứ tiêu chuẩn?

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

đó là terribly chậm: github.com/fabienrenaud/java-json-benchmark thời gian gần đây tại công việc, tôi tăng gấp đôi (cắt sử dụng CPU trong nửa, độ trễ cắt trong ngưng) hiệu suất của máy chủ sản của chúng tôi bằng cách chuyển tất cả org.json ser / cuộc gọi deserialization sử dụng jackson.
fabien

0

Hãy thử một lần:

https://github.com/RichardHightower/boon

Nó là xấu xa nhanh chóng:

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

Đừng tin tôi ... hãy kiểm tra điểm chuẩn.

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

(Lên đến 4x là một số trường hợp và trong số 100 thử nghiệm. Nó cũng có chế độ lớp phủ chỉ mục thậm chí còn nhanh hơn. Nó còn trẻ nhưng đã có một số người dùng.)

Nó có thể phân tích cú pháp JSON sang Bản đồ và Danh sách nhanh hơn bất kỳ lib nào khác có thể phân tích cú pháp JSON DOM và không có chế độ Lớp phủ chỉ mục. Với chế độ Boon Index Overlay, nó thậm chí còn nhanh hơn.

Nó cũng có chế độ lax JSON rất nhanh và chế độ phân tích cú pháp PLIST. :) (và có bộ nhớ siêu thấp, trực tiếp từ chế độ byte với mã hóa UTF-8 khi đang di chuyển).

Nó cũng có chế độ JSON sang JavaBean nhanh nhất.

Nó là mới, nhưng nếu API tốc độ và đơn giản là những gì bạn đang tìm kiếm, tôi không nghĩ rằng có một API nhanh hơn hoặc tối giản hơn.


bạn có thể cung cấp một liên kết để cập nhật tài liệu cho phiên bản mới nhất không? Cho đến hôm nay, tôi đã tìm thấy 0,4, nhưng không thể dễ dàng tìm thấy một liên kết tài liệu phù hợp hoặc hướng dẫn cho phiên bản đó. Cảm ơn
Bizmarck

Dưới đây là hướng dẫn github.com/RichardHightower/boon/wiki/Boon-JSON-in-five-minutes Boon nằm trong repo maven công khai. Đó là ở mức 0,27 hoặc hơn.
RickHigh

richardhightower.github.io/site/release có 0,4, vì vậy tôi nghĩ đó là mới nhất. Tôi đã kiểm tra Boon cho một dự án tại nơi làm việc, nó có chú thích tương đương với @JsonIgnore của Jackson không?
Bizmarck

boon nằm ở phần dưới của hiệu suất ser / deserialization: github.com/fabienrenaud/java-json-benchmark Chọn jackson hoặc dsljson cho hiệu suất. @RickHigh: Tôi không thể mở một vấn đề trên github của bạn, tôi sẵn sàng cải thiện điểm chuẩn của mình hoặc sửa giải thích nếu có bất cứ điều gì sai / đó là tôi đã bỏ lỡ.
fabien

0

Tùy thuộc vào định dạng JSON đầu vào (chuỗi / tệp) tạo jSONString. Đối tượng lớp Message Message tương ứng với JSON có thể được lấy như dưới đây:

Tin nhắn dirFromJSON = new ObjectMapper (). ReadValue (jSONString, Message. Class);


0

Cách dễ nhất là bạn có thể sử dụng phương thức softconvertvalue này, đây là một phương thức tùy chỉnh trong đó bạn có thể chuyển đổi jsonData thành lớp Dto cụ thể của mình.

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);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.