org.json을 효율적으로 매핑하는 방법.JSONObject to POJO?
서드파티 라이브러리를 사용하여 JSON 형식의 데이터를 가져오고 있습니다.도서관은 나에게 데이터를 제공한다.org.json.JSONObject
이 맵을 만들고 싶다.JSONObject
POJO(Plain Old Java Object)로 변환하여 액세스/코드를 심플하게 합니다.
매핑에는 현재ObjectMapper
다음 방법으로 잭슨 도서관에서 가져옵니다.
JSONObject jsonObject = //...
ObjectMapper mapper = new ObjectMapper();
MyPojoClass myPojo = mapper.readValue(jsonObject.toString(), MyPojoClass.class);
제가 이해하기로는, 위의 코드는 상당히 최적화될 수 있습니다. 왜냐하면 현재 데이터에는JSONObject
는, 이미 해석되고 있는 것으로, 를 사용해 시리얼라이제이션-디시리얼라이제이션 체인에 다시 보내집니다.JSONObject.toString()
method에 이어서ObjectMapper
.
이러한 2개의 변환을 피하고 싶다(toString()
및 해석).를 사용할 수 있는 방법이 있습니까?JSONObject
데이터를 POJO에 직접 매핑할 수 있을까요?
일부 JSON 데이터(개체)를 추상적으로 표현하고 JSON 데이터()com.fasterxml.jackson.databind.JsonNode
를 추상적으로 표현한 Jackson 라이브러리를 사용할 예정이기 때문에 하나의 표현에서 다른 표현으로 변환하면 구문 분석-직렬화-파스 프로세스에서 벗어날 수 있습니다.그래서, 그 대신,readValue
받아들이는 방법String
, 이 버전을 사용하고,JsonParser
:
JSONObject jsonObject = //...
JsonNode jsonNode = convertJsonFormat(jsonObject);
ObjectMapper mapper = new ObjectMapper();
MyPojoClass myPojo = mapper.readValue(new TreeTraversingParser(jsonNode), MyPojoClass.class);
JSON은 매우 단순한 형식이기 때문에 쉽게 작성할 수 있습니다.convertJsonFormat
손으로.제 시도는 이렇습니다.
static JsonNode convertJsonFormat(JSONObject json) {
ObjectNode ret = JsonNodeFactory.instance.objectNode();
@SuppressWarnings("unchecked")
Iterator<String> iterator = json.keys();
for (; iterator.hasNext();) {
String key = iterator.next();
Object value;
try {
value = json.get(key);
} catch (JSONException e) {
throw new RuntimeException(e);
}
if (json.isNull(key))
ret.putNull(key);
else if (value instanceof String)
ret.put(key, (String) value);
else if (value instanceof Integer)
ret.put(key, (Integer) value);
else if (value instanceof Long)
ret.put(key, (Long) value);
else if (value instanceof Double)
ret.put(key, (Double) value);
else if (value instanceof Boolean)
ret.put(key, (Boolean) value);
else if (value instanceof JSONObject)
ret.put(key, convertJsonFormat((JSONObject) value));
else if (value instanceof JSONArray)
ret.put(key, convertJsonFormat((JSONArray) value));
else
throw new RuntimeException("not prepared for converting instance of class " + value.getClass());
}
return ret;
}
static JsonNode convertJsonFormat(JSONArray json) {
ArrayNode ret = JsonNodeFactory.instance.arrayNode();
for (int i = 0; i < json.length(); i++) {
Object value;
try {
value = json.get(i);
} catch (JSONException e) {
throw new RuntimeException(e);
}
if (json.isNull(i))
ret.addNull();
else if (value instanceof String)
ret.add((String) value);
else if (value instanceof Integer)
ret.add((Integer) value);
else if (value instanceof Long)
ret.add((Long) value);
else if (value instanceof Double)
ret.add((Double) value);
else if (value instanceof Boolean)
ret.add((Boolean) value);
else if (value instanceof JSONObject)
ret.add(convertJsonFormat((JSONObject) value));
else if (value instanceof JSONArray)
ret.add(convertJsonFormat((JSONArray) value));
else
throw new RuntimeException("not prepared for converting instance of class " + value.getClass());
}
return ret;
}
알아둬, 잭슨의 가족은JsonNode
몇 가지 추가 유형을 나타낼 수 있습니다(예:BigInteger
,Decimal
, 등) 위의 코드가 다음 사항을 모두 커버하기 때문에 이러한 기능은 필요하지 않습니다.JSONObject
를 나타낼 수 있습니다.
오래된 질문에 답을 덧붙이긴 하지만...
Jackson은 org.json 타입과 바인드 할 수 있습니다.일반적으로 JSON에 대한 효과적인 직렬화 및 역직렬화를 통해 바인딩할 수 있는 모든 유형 간에 변환할 수 있습니다.
JsonOrgModule을 등록한 경우 ObjectMapper에서 직접 변환할 수 있습니다.
@Test
public void convert_from_jsonobject() throws Exception {
JSONObject obj = new JSONObject().put("value", 3.14);
ObjectMapper mapper = new ObjectMapper().registerModule(new JsonOrgModule());
PojoData data = mapper.convertValue(obj, PojoData.class);
assertThat(data.value, equalTo(3.14));
}
@Test
public void convert_to_jsonobject() throws Exception {
PojoData data = new PojoData();
data.value = 3.14;
ObjectMapper mapper = new ObjectMapper().registerModule(new JsonOrgModule());
JSONObject obj = mapper.convertValue(data, JSONObject.class);
assertThat(obj.getDouble("value"), equalTo(3.14));
}
public static final class PojoData {
public double value;
}
이게 효과적으로 연재되고 있다고 말씀드렸잖아요?맞습니다. 입력 객체를 토큰 버퍼로 직렬화합니다. 토큰 버퍼는 JSON 구문 분석 이벤트의 스트림을 나타내지만 입력 데이터를 주로 참조할 수 있기 때문에 문자열 구축 등의 영향은 적습니다.그런 다음 이 스트림을 역직렬라이저에 공급하여 출력 객체를 생성합니다.
JSONObject를 JsonNode로 변환하는 제안과 비슷하지만 훨씬 더 일반적입니다.JsonNode를 중간 또는 토큰버퍼로 구성해도 오버헤드가 발생하지 않습니다.
Jackson과 관련이 없다면 편리한 Google-gson 라이브러리를 대안으로 사용할 수 있습니다.1개의 항아리만 필요하며 사용법은 매우 간단합니다.
Java 개체를 JSON 문자열로 변환하려면 다음 절차를 수행합니다.
String json_string = new Gson().toJson(an_object);
JSON 문자열에서 Java 객체 생성:
MyObject obj = new Gson().fromJson(a_json_string, MyObject.class);
잭슨과 비교해서 퍼포먼스는 잘 모르겠지만, 이것보다 더 간단하기는 어렵지만...Gson은 안정적이고 널리 사용되는 도서관입니다.
https://code.google.com/p/google-gson/ 를 참조해 주세요.
Gson을 사용하여 보다 간단한 방법.
JSONObject jsonObject = //...
PojoObject objPojo = new Gson().fromJson(jsonObject.toString(), PojoObject.class);
이건 나한테 효과가 있었어.
언급URL : https://stackoverflow.com/questions/20534862/how-to-efficiently-map-a-org-json-jsonobject-to-a-pojo
'source' 카테고리의 다른 글
웹 팩 로더와 플러그인의 차이점 (0) | 2023.02.14 |
---|---|
ORA-01810: 포맷 코드가 2회 표시됨 (0) | 2023.02.14 |
다른 지시문 안에 각도 지시문 사용 (0) | 2023.02.14 |
브라우저에서 패스워드 저장을 요구받으려면 어떻게 해야 하나요? (0) | 2023.02.10 |
react-module, 번들 (0) | 2023.02.10 |