JSON 데이터를 Java 객체로 변환


262

Java 조치 메소드 내의 JSON 문자열에서 특성에 액세스 할 수 있기를 원합니다. 간단히 말하면 문자열을 사용할 수 있습니다 myJsonString = object.getJson(). 아래는 문자열이 어떻게 보이는지에 대한 예입니다.

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

이 문자열에는 모든 JSON 객체에 다른 JSON 객체의 배열이 포함됩니다. 의도 된 오브젝트가 다른 JSON 오브젝트를 포함하는 그룹 특성을 보유하는 ID 목록을 추출하는 것입니다. Google의 Gson을 잠재적 인 JSON 플러그인으로 보았습니다. 누구나이 JSON 문자열에서 Java를 생성하는 방법에 대한 지침을 제공 할 수 있습니까?



답변:


329

Google의 Gson을 잠재적 인 JSON 플러그인으로 보았습니다. 누구나이 JSON 문자열에서 Java를 생성하는 방법에 대한 지침을 제공 할 수 있습니까?

Google Gson 은 제네릭 및 중첩 된 Bean을 지원합니다. []JSON의 배열을 나타내며 같은 자바 컬렉션에 매핑해야합니다 List아니면 그냥 일반 자바 배열입니다. {}JSON에서 객체를 나타내며 자바에 매핑해야 Map하거나 일부 자바 빈즈 클래스입니다.

여러 속성을 가진 JSON 객체가 있으며이 속성은 groups동일한 유형의 중첩 객체 배열을 나타냅니다. 이것은 Gson으로 다음과 같은 방식으로 구문 분석 할 수 있습니다.

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

상당히 간단하지 않습니까? 적절한 JavaBean을 가지고 호출하십시오 Gson#fromJson().

또한보십시오:


4
수행자? 실제로 측정 했습니까? GSON 합리적인 기능 세트를 가지고 있지만, 나는 성능이 약점의 ([따라 종류라고 생각 cowtowncoder.com/blog/archives/2009/09/entry_326.html] 내가 GSON 정말 세터가 필요하지 않은 생각과 예에 관해서) 필드를 기반으로했습니다. 따라서 코드를 약간 단순화 할 수 있습니다.
StaxMan

3
나는 안드로이드 앱에서 사용합니다. 가능한 가장 빠른 솔루션은 아니지만 지금까지 사용자의 성능 부족을 정당화하도록 프로그래밍하기에는 간단합니다. 아마도 이후 버전의 앱에서는 더 빠른 솔루션을 위해 제거 될 것입니다.
Janusz

1
Wrt 속도, 충분히 빠르면 충분히 빠릅니다. 방금 예상되는 우수한 성능에 대해 언급했습니다. 기능별 현명한 Jackson은 동일한 모든 중첩, 계층화, 제네릭을 처리하므로 속도 차이가 발생하지 않습니다. 게터와 세터가 있다고해도 측정 가능한 방식으로 성능에 영향을 미치지 않으므로 (내가 알고있는 패키지의 경우) 분명히 거기에있을 수 있습니다.
StaxMan

97
"package com.stackoverflow.q1688099;의 경우 +1 어떤 이유로 그것은 나를 괴롭 혔습니다.
GargantuChet 2

1
public String toString () {return new Gson (). toJson (this); // 각 변수를 쓰는 대신 이것을 사용하십시오.}
Prakash

45

Gson의 Bwaaaaare! 그것은 아주 아주 좋은, 멋진,하지만 당신은 단순한 객체 이외의 다른 작업을 수행 할 두 번째는, 당신은 쉽게 (아닌 자신의 시리얼 구축을 시작해야 할 수있는 하드를).

또한 객체 배열이 있고 일부 JSON을 해당 객체 배열로 직렬화 해제하면 실제 유형은 손실됩니다! 전체 개체는 복사되지 않습니다! XStream을 사용하십시오. jsondriver를 사용하고 적절한 설정을 설정하면 추악한 유형이 실제 json으로 인코딩되어 아무것도 풀리지 않습니다. 진정한 직렬화를 위해 지불해야 할 작은 가격 (못생긴 json).

참고 잭슨은 이러한 문제를 해결하고, 빠른 GSON보다.


2
나는이 문제를 해결합니다 (그리고 잭슨의 모든 주석을 피할 수) GSON의 포크를 작성했습니다 : github.com/winterstein/flexi-gson
다니엘 Winterstein

26

이상하게도 지금까지 언급 한 유일한 JSON 프로세서는 GSON이었습니다.

더 좋은 선택은 다음과 같습니다.

  • Jackson ( Github )-강력한 데이터 바인딩 (JSON과 POJO 간), 스트리밍 (초고속), 트리 모델 (유형이없는 액세스에 편리함)
  • Flex-JSON- 고도로 구성 가능한 직렬화

편집 (2013 년 8 월) :

고려해야 할 사항 하나 더 :

  • Genson -Jackson과 유사한 기능으로 개발자가 쉽게 구성 할 수 있음

15

또는 Jackson과 함께 :

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

이 줄 것이다 오류 수 없습니다 START_OBJECT 중 토큰는 java.util.HashSet의 직렬화 예
Dipen Chawla는

7

변경으로 인해 이미 http://restfb.com/ 을 사용하는 응용 프로그램에있는 경우 다음을 수행 할 수 있습니다.

import com.restfb.json.JsonObject;

...

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

기타


솔루션이 더 짧고 이해하기 쉬우 며 왜 3 개의 upvotes 만 받는가? 문제가 있습니까?
Jeff

4

변환 JSONObject하기 쉬운 Java 코드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());

    }
}

JSP에서 이러한 json 속성에 액세스하는 방법은 무엇입니까?
Zoran777

JSP 페이지에서 사용하지 않으려는 경우 코드는 여전히 동일합니다. Employee.java 클래스는 그대로입니다. 그러나 LoadFromJSON.java로 작성된 코드는 모든 클래스를 올바르게 가져 와서 jsp 페이지에 복사됩니다. 전혀 변화가 없습니다.
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

키 또는 값이있는 특수 맵을 특수 맵으로 사용하는 경우 Google의 구현으로 고려되지 않습니다.


2

표준 물건에 어떤 문제가 있습니까?

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

그것은 정말 느린 : github.com/fabienrenaud/java-json-benchmark는 최근 직장에서, 내가 모든 org.json 빼앗아 / 역 직렬화 통화를 전환하여 우리의 찌르다 서버의 성능 (절반의 CPU 사용 컷, 정지 대기 시간 컷)을 두 배로 잭슨을 사용합니다.
fabien

0

시도해보십시오 :

https://github.com/RichardHightower/boon

그것은 사악하다 :

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

내 말을 받아들이지 마라 ... 개틀링 벤치 마크를 확인하십시오.

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

(경우에 따라 최대 4 배가되며 100 대 테스트 중입니다. 인덱스 오버레이 모드도 더 빠릅니다. 젊지 만 이미 일부 사용자가 있습니다.)

다른 lib가 JSON DOM으로 구문 분석 할 수 있고 인덱스 오버레이 모드가없는 것보다 빠르게 JSON을 맵 및 목록으로 구문 분석 할 수 있습니다. Boon Index Overlay 모드에서는 훨씬 빠릅니다.

또한 매우 빠른 JSON lax 모드와 PLIST 파서 모드가 있습니다. :) (그리고 UTF-8 인코딩으로 바이트 모드에서 직접 메모리가 매우 적습니다).

또한 JSON에서 JavaBean 모드까지 가장 빠릅니다.

새로운 기능이지만 속도와 간단한 API를 찾고 있다면 더 빠르거나 더 미니멀 한 API가 없다고 생각합니다.


최신 버전의 최신 문서에 대한 링크를 제공 할 수 있습니까? 오늘부터 0.4를 찾았지만 해당 버전에 맞는 문서 링크 또는 자습서를 쉽게 찾을 수 없습니다. 감사합니다
Bizmarck

다음은 튜토리얼 github.com/RichardHightower/boon/wiki/Boon-JSON-in-5- 분입니다. Boon은 공개 Maven 저장소에 있습니다. 0.27 정도입니다.
RickHigh

richardhightower.github.io/site/releases 는 0.4이므로 최신 버전이라고 생각했습니다. 직장에서 프로젝트에 대해 Boon을 확인하고 있는데 Jackson의 @JsonIgnore와 동등한 주석이 있습니까?
Bizmarck

이익은 SER / 역 직렬화 성능의 하단에 있습니다 : github.com/fabienrenaud/java-json-benchmark 잭슨이나 성능에 대한 dsljson를 선택합니다. @ RickHigh : github에서 문제를 열 ​​수 없었습니다. 틀린 것이 있거나 누락 된 부분이 있으면 벤치 마크를 개선하거나 해석을 기꺼이 수정하십시오.
fabien

0

입력 JSON 형식 (문자열 / 파일)에 따라 jSONString을 작성하십시오. JSON에 해당하는 샘플 메시지 클래스 객체는 다음과 같이 얻을 수 있습니다.

메시지 msgFromJSON = 새 ObjectMapper (). readValue (jSONString, Message.class);


0

가장 쉬운 방법은 jsonData를 특정 Dto 클래스로 변환 할 수있는 사용자 정의 방법 인이 softconvertvalue 메소드를 사용할 수 있다는 것입니다.

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);
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.