JSON을 CSV로 변환하는 동안 JSON 키의 순서 유지


82

여기에 제공된 JSON 라이브러리 http://www.json.org/java/index.html 을 사용하여 필요한 json 문자열을 CSV로 변환하고 있습니다. 그러나 내가 가진 문제는 변환 후 키의 순서가 손실된다는 것입니다.

다음은 전환 코드입니다.

    JSONObject jo = new JSONObject(someString);
    JSONArray ja = jo.getJSONArray("items");
    String s = CDL.toString(ja);
    System.out.println(s);

다음은 "someString"의 내용입니다.

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
    ]
}

결과는 다음과 같습니다.

WO,QU,WR,QA,NO
hasd,asd,qwe,end,qwer

내가 기대하는 것은 키의 순서를 유지하는 것입니다.

WR,QU,QA,WO,NO
qwe,asd,end,hasd,qwer

이 라이브러리를 사용하여이 결과를 얻을 수있는 방법이 있습니까? 그렇지 않은 경우 결과에서 키 순서를 유지하는 기능을 제공하는 다른 라이브러리가 있습니까?


4
사전이 정렬되지 않았습니다. JSON이 주문을 보장한다고 생각하지도 않습니다.
Falmarri 2010

2
정보에 대해서 감사드립니다. 하지만 내 응용 프로그램에서 JSON을 사용하는 것 외에는 선택의 여지가 없으며 응용 프로그램은 키 순서를 유지해야합니다. (
Hery

제 경우 문제는 주문의 부족이 아니라 결정적이지 않습니다. 때때로 나는 키 foo전에 bar그리고 때로는 bar전에 키를 얻습니다 foo. 이것은 테스트를 작성하기 어렵게 만듭니다.
Sridhar Sarnobat

나는 또한 이러한 요구에 직면했지만 실시간 테스트 중에 빠른 로그 비교를위한 것입니다. 처리량이 많은 애플리케이션을 위해 새로 생성 된 로그와 이전에 생성 된 로그를 실시간으로 비교해야합니다. 이를 수행하는 다른 방법이 있지만 로그가 JSON 형식 인 것을 선호합니다. 그러나 CPU 사용을 최소화하기 위해 직접 문자열 JSON 작성기를 작성하고 있습니다. 내부 구조가 전혀 필요하지 않으며 로그의 빠른 문자열 비교를 위해 키 순서를 유지할 수 있습니다. 예측 가능한 순서를 원하는 좋은 이유가 있습니다.
Joe Lapp

JSON을 구체적으로 정렬 된 CSV 파일로 변환하는 고유 한 코드를 작성하면 두 형식을 모두 존중할 수 있습니다.
Martijn Scheffer

답변:


95

이를 수행하는 (해키) 방법이 있지만 ...해서는 안됩니다.

JSON에서 객체는 다음과 같이 정의됩니다.

객체는 이름 / 값 쌍의 순서가 지정되지 않은 집합입니다.

http://json.org를 참조하십시오 .

대부분의 JSON 구현은 (정의상) 중요하지 않기 때문에 객체의 이름 / 값 쌍 순서를 유지하려고 노력하지 않습니다.

주문을 보존하려면 데이터 구조를 재정의해야합니다. 예 :

{
    "items":
    [
        [
            {"WR":"qwe"},
            {"QU":"asd"},
            {"QA":"end"},
            {"WO":"hasd"},
            {"NO":"qwer"}
        ],
    ]
}

또는 더 간단하게 :

{
    "items":
    [
        {"WR":"qwe"},
        {"QU":"asd"},
        {"QA":"end"},
        {"WO":"hasd"},
        {"NO":"qwer"}
    ]
}

후속 조치

정보 주셔서 감사합니다.하지만 내 애플리케이션에서 JSON을 사용할 수밖에 없으며 내 애플리케이션은 JSON 개체의 정의에 관계없이 키의 순서를 유지해야합니다. JSON 파일의 형식을 변경할 수 없습니다. 게다가...

해당 파일 구조를 설계 한 사람과 열심히 대화해야하며 변경하지 못하게해야합니다. 그것은 / 그들은 명백히 잘못되었습니다. 당신은 필요 그들을 설득.

그들이 정말로 당신이 그것을 바꾸도록 허락하지 않는다면 :

  • 당신은 그것을 JSON이라고 부르지 말라고 주장해야합니다 .
  • 순서를 유지하는 일부 JSON 구현을 찾을 수 없다면이 "JSON이 아닌"형식을 처리하기 위해 특별히 코드를 작성 / 수정해야한다는 점을 지적해야합니다. 그들이 유료 고객 인 경우, 귀하가해야 할 추가 작업에 대해 지불해야합니다.
  • 다른 도구에서 "not JSON"을 사용해야하는 경우 문제가 될 수 있다는 점을 지적해야합니다. 실제로이 문제는 계속해서 발생할 것입니다 ...

이런 일은 정말 나쁘다. 한편으로, 귀하의 소프트웨어는 상호 운용성을 촉진하도록 설계된 잘 확립 된 / 오래 지속되는 사양을 위반하게됩니다. 반면에,이 절름발이 (JSON이 아님!) 파일 형식을 디자인 멍청이 는 아마도 다른 사람들의 시스템 등을 뒤흔들고있을 것입니다. 시스템이 그들의 말도 안되는 일에 대처할 수 없기 때문 입니다.

최신 정보

이 주제에 대한 JSON RFC (RFC 7159)의 내용도 읽어 볼 가치가 있습니다 . 다음은 일부 발췌입니다.

RFC 4627이 발표 된 이후 몇 년 동안 JSON은 매우 널리 사용되었습니다. 이 경험을 통해 특정 패턴이 드러났지만 사양에 따라 허용되지만 상호 운용성 문제가 발생했습니다.

JSON (JavaScript Object Notation)은 구조화 된 데이터의 직렬화를위한 텍스트 형식입니다. ...

JSON은 네 가지 기본 유형 (문자열, 숫자, 부울 및 널)과 두 가지 구조화 된 유형 (객체 및 배열)을 나타낼 수 있습니다.

개체는 0 개 이상의 이름 / 값 쌍 의 순서지정되지 않은 컬렉션입니다. 여기서 이름은 문자열이고 값은 문자열, 숫자, 부울, null, 개체 또는 배열입니다.

JSON 구문 분석 라이브러리는 호출 소프트웨어에 개체 멤버의 순서를 표시하는지 여부가 다른 것으로 관찰되었습니다. 동작이 멤버 순서에 의존하지 않는 구현은 이러한 차이의 영향을받지 않는다는 점에서 상호 운용이 가능합니다.


6
@Hery-bill them :-)
Stephen C

3
@YogeshSomani- "솔루션"은 적절한 JSON 라이브러리를 확보하고 키 순서를 유지하도록 "해킹"하는 것입니다. 예를 들어 gary의 답변을 참조하십시오. 그러나 이와 같은 JSON 사양의 남용을 장려하는 것은 잘못된 IDEA이기 때문에 표준 JSON 라이브러리가이를 수행 할 것으로 기 대해서는 안됩니다. 실제 솔루션은 JSON을 올바르게 사용하도록 애플리케이션을 수정하는 것입니다.
Stephen C

10
가장 순수하고 절대적인 것이 좋지만, 스스로를 속이지 말자. JSON 파일이 정의 된 값의 순서를 보존해야하는 실제 시나리오가 있습니다. 어떤 순서로든 전달하고 받아들이는 것은 기본적인 json 접근 방식이지만 json 문서를 가져와 동등하게 직렬화 / 역 직렬화 할 수있는 능력과는 다른 것으로 생각합니다. 그것은 주문 요구 보존하는 등 다른 표준 WDDX, HTML의 문서를 형성하기 위해 JSON 문서를 받아 사용 할 수있는 일반적인 사용 사례입니다
앤드류 노먼

3
@AndrewNorman- "필요"에 대해 말한 내용이 정말 사실이라면 사양이 변경되었을 것입니다. 현실은 JSON에서 다른 방식으로 순서를 표현하기 쉽다는 것입니다.
Stephen C

2
JSON은 정보가 키 순서로 인코딩되지 않도록 요구합니다. 그렇지 않으면 JSON이 아닙니다. 직렬화의 일관성은 다른 문제입니다. 단일 앱 내에서 일반적으로 공통 JSON 라이브러리를 사용하여 일관성을 보장 할 수 있지만 단일 솔루션이 여러 플랫폼 또는 프레임 워크에 걸쳐있는 경우와 같은 예외가 있습니다. 이러한 경우 불일치를 처리하는 방법을 찾거나 (비 효율성을 유발 함) 일관성을 보장하는 방법을 찾아야합니다. 두 방법 모두 유효합니다.
Joe Lapp

47

질서를 유지하는 것은 아주 간단합니다. DB 레이어에서 UI 레이어로 순서를 유지하는 데 동일한 문제가 발생했습니다.

JSONObject.java 파일을 엽니 다. 내부적으로 순서를 유지하지 않는 HashMap을 사용합니다.

LinkedHashMap으로 변경하십시오.

    //this.map = new HashMap();
    this.map = new LinkedHashMap();

이것은 나를 위해 일했습니다. 댓글로 알려주세요. JSON 라이브러리 자체에는 JSONOrderdObject.java와 같이 순서를 유지하는 또 다른 JSONObject 클래스가 있어야합니다. 나는 이름을 선택하는 데 매우 가난합니다.


2
svn checkout json-simple. 수정 파일 org.json.simple.JSONObject, <code> JOSNObject extends LinkedHashMap ... </ code> from <code> .. HashMap .. </ code>, fix the imports and it works me. v1.1.1.
Marku 2013-06-29

2
이것은 시도해 본 적이없는 훌륭한 단선 솔루션입니다. 완벽하게 작동하며 다른 코드를 변경할 필요가 없습니다. +1
DaaaahWhoosh 2015 년

대단한 수정. 당신은 영웅 선생님이야
그레고리 Nowakowski

작동하지 않았고, 가져 오기를 추가하고, 말한대로 변경했으며, 심지어 이렇게하려고 시도했습니다. this.map = new LinkedHashMap<String, Object>();여전히 작동하지 않습니다. 도와주세요 ?
Tarek

4
하하 정말? 필요에 맞게 JSON 라이브러리를 수정 하시겠습니까? 나는 이것이 회사 지식 기반에서 내려가는 것을 상상할 수 있습니다. "mvn을 새로 설치하고, jar를 다운로드하고, 찾아서 디 컴파일 한 다음 HashMap을 LinkedHashMap으로 바꿉니다." 이것은 여러 개발자 팀에 적합합니다.
Chris Neve

22

JSONObject.java어떤지도를 통과하든 가져갑니다. LinkedHashMap또는 일 수 있으며 맵이 null 인 경우에만 TreeMap걸립니다 hashmap.

다음은 JSONObject.java지도 검사를 수행 할 클래스 생성자입니다 .

 public JSONObject(Map paramMap)
  {
    this.map = (paramMap == null ? new HashMap() : paramMap);
  }

따라서 json 객체 구조를 빌드하기 전에 LinkedHashMap다음과 같이 생성자에 전달하십시오.

LinkedHashMap<String, String> jsonOrderedMap = new LinkedHashMap<String, String>();

jsonOrderedMap.put("1","red");
jsonOrderedMap.put("2","blue");
jsonOrderedMap.put("3","green");

JSONObject orderedJson = new JSONObject(jsonOrderedMap);

JSONArray jsonArray = new JSONArray(Arrays.asList(orderedJson));

System.out.println("Ordered JSON Fianl CSV :: "+CDL.toString(jsonArray));

따라서 JSONObject.java클래스 를 변경할 필요가 없습니다 . 누군가에게 도움이되기를 바랍니다.


3
좋은 대답은 일반 자바에서 작동하지만 Android에서는 작동하지 않습니다. 안드로이드에서 org.json.JSONObject를 확인했는데, 안드로이드가 여전히 내부적으로 생성 된 해시 맵을 사용하는 것은 유감입니다. paramMap에서 HashMap으로 이름 / 값 쌍만 복사합니다 ... :(
正宗 白 布鞋

JsonObject를 주문했지만 JsonArray에 해당 개체를 추가하려고하면 정렬되지 않은 개체가 제공됩니다. 나는 배열에 객체를 넣어야하고, 배열의 객체가 필요하고 헤더를 배열에 넣고 다시 보냈습니다. 예 : 하나의 개체; {CUSTOMER_SECTOR_ID = 611, CUSTOMER_NO = 0000003204, CUSTOMER_NAME = MARMARİS-KARAS GIDA KARAS TÜKETİM MADDELERİ GIDA LOJ.} 두 개의 개체를 배열에 넣으면 다음과 같은 결과가 나타납니다. [{ "CUSTOMER_NAME": "SILA GIDA PAZARLAMA": "CUSTOMER_NO =" 0000003122 ","CUSTOMER_SECTOR_ID ":"611 "}, {"CUSTOMER_NAME ":"M ":"0013114714 ","CUSTOMER_SECTOR_ID ":"611 "}] 보시다시피 잘못되었습니다. 어떻게 고칠 수 있습니까?
Sahin Yanlık 2014

2
@Deepak Nagaraj. 나는 귀하의 솔루션을 시도했지만 작동하지 않았으며 JSONObjectLinkedHashMap. 당신은 org.jsonlib 를 사용하고 있습니까?
Ismail Sen

1
이것은 당신이 제공하는 것이 무엇이든 내부적으로 org.json정의 합니다. @Deepak 당신이 사용한 구현을 알려줄 수 있습니까? HashMapMap
Campa

8
org.json라이브러리 에서는 작동하지 않습니다 . 새 JSONObject객체 를 생성하고 지도를 인수로 전달하면 항상 HashMap. 생성자는 먼저 새지도를 만든 this.map = new HashMap<String, Object>();다음지도를 반복하여 모든 요소를 HashMap.
itachi

13

이러한 종류의 문제에 대해보다 장황하지만 광범위하게 적용 할 수있는 해결책은 한 쌍의 데이터 구조를 사용하는 것입니다. 순서를 포함하는 목록과 관계를 포함하는 맵입니다.

예를 들면 :

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
    ],
    "itemOrder":
        ["WR", "QU", "QA", "WO", "NO"]
}

itemOrder 목록을 반복하고이를 사용하여 맵 값을 조회합니다. kludges없이 주문이 보존됩니다.

이 방법을 여러 번 사용했습니다.


지도는 단순한 키 - 값 쌍 ...가 아닌 경우이 복잡해진다
zfj3ub94rf576hc4eegm

10

reflect를 사용하는 또 다른 해키 솔루션 :

JSONObject json = new JSONObject();
Field map = json.getClass().getDeclaredField("map");
map.setAccessible(true);//because the field is private final...
map.set(json, new LinkedHashMap<>());
map.setAccessible(false);//return flag

1
나는 대답하지 않았다
M. 우스만 칸

1
트릭은 기본 HashMap 대신 LinkedHashMap을 사용하도록 클래스를 내부적으로 수정하여 JSON 객체가 입력 한 순서대로 데이터를 갖도록 만드는 것입니다. 이것은 직접 정렬되지는 않지만 구문 분석 된 데이터가 이미 정렬 되었기 때문에 저에게 효과적이었습니다. .
fabe

좋아 보이지만 Json String AFTER 구문 분석 방법 map.set (json, new LinkedHashMap <> ()); Json String이 생성자에 전달되기 때문에 맞습니까? 새로운 JSONObject (jsonString)처럼.
M. Usman Khan

또한 이것은 작동하지 않았습니다. "map"필드가없고 이미 LinckedHashMap 인 "nameValuePairs"필드가 있으며 여전히 작동하지 않습니다.
M. Usman Khan

1
사용중인 JSONObject 구현은 무엇입니까? 나는 org.json 버전 20140107을 사용하고 있으며 순서를 유지해야했고 그것이 나를 위해 작동하는 방식입니다.
fabe


4

같은 문제를 만났을 때 저자가 사용한 최종 솔루션은 사용자 정의 ContainerFactory를 사용하는 것으로 구성되었다고 생각합니다.

public static Values parseJSONToMap(String msgData) {
    JSONParser parser = new JSONParser();
    ContainerFactory containerFactory = new ContainerFactory(){
        @Override
        public Map createObjectContainer() {
            return new LinkedHashMap();
        }

        @Override
        public List creatArrayContainer() {
            return null;
        }
    };
    try {
        return (Map<String,Object>)parser.parse(msgData, containerFactory);
    } catch (ParseException e) {
        log.warn("Exception parsing JSON string {}", msgData, e);
    }
    return null;
}  

http://juliusdavies.ca/json-simple-1.1.1-javadocs/org/json/simple/parser/JSONParser.html#parse(java.io.Reader,org.json.simple.parser.ContainerFactory) 참조


정말 훌륭하고 실용적인 솔루션입니다. containerFactory에 대한 로컬 익명 내부 클래스를 작성하는 것은 어떻습니까?
Shailesh Saxena

3

해결되었습니다.

여기 https://code.google.com/p/json-simple/ 에서 JSON.simple 라이브러리를 사용하여 JSON 문자열을 읽고 키 순서를 유지하고 여기 http://sourceforge.net/ 에서 JavaCSV 라이브러리를 사용했습니다 . projects / javacsv / -CSV 형식으로 변환합니다.


이것이 효과가 있다는 것에 놀랐습니다. JSONObject 클래스 ( code.google.com/p/json-simple/source/browse/trunk/src/main/java/… ) 의 코드와 주석을 모두 읽은 바에 따르면 보존 할 작업이 없습니다. 키의 순서.
스티븐 C

1
여기서 전체 솔루션을 지정하지는 않았지만 json-simple은 json 객체를 저장하는 데 사용되는 데이터 구조를 지정할 수있는 팩토리를 제공한다는 것입니다. LinkedHashMap을 사용하도록 지정하기 만하면됩니다.
Hery

@Hery, 나는 같은 문제에 직면했지만 해결할 수 없었습니다. 내가 사용하는 org.json변환에 List<LinkedHahMap>JSONArray을 만들기 위해 CSV의는 CSV아니지만 내와 같은 순서로 생성됩니다 List . 여기에 제시 한 두 개의 lib를 사용하려고 시도했지만.으로 변환하는 방법을 찾을 수 없습니다 CSV. 자세한 내용 을 알려주시겠습니까?
Ismail Sen

2

나는 이것이 해결되었고 오래 전에 질문이 제기되었다는 것을 알고 있지만, 비슷한 문제를 다루고 있으므로 이것에 대해 완전히 다른 접근 방식을 제공하고 싶습니다.

배열의 경우 "배열은 정렬 된 값 모음"이라고 표시됩니다. 에서 http://www.json.org/ -하지만 개체가 ( "객체는 이름 / 값 쌍의 정렬되지 않은 집합입니다.") 정렬되지 않습니다.

왜 그 객체가 배열에 있는지 궁금합니다. 이것은 거기에없는 순서를 의미합니다.

{
"items":
[
    {
        "WR":"qwe",
        "QU":"asd",
        "QA":"end",
        "WO":"hasd",
        "NO":"qwer"
    },
]
}

따라서 해결책은 키를 "실제"배열에 넣고 데이터를 다음과 같이 각 키에 객체로 추가하는 것입니다.

{
"items":
[
    {"WR": {"data": "qwe"}},
    {"QU": {"data": "asd"}},
    {"QA": {"data": "end"}},
    {"WO": {"data": "hasd"}},
    {"NO": {"data": "qwer"}}
]
}

그래서 이것은 원래의 모델링과 그 의도를 재고하려는 접근 방식입니다. 그러나 모든 관련 도구가 원래 JSON 배열의 순서를 유지할지 테스트하지 않았으며 궁금합니다.


1
이것은 내가 키에 대한 조회를 할 수 없도록합니다.
mickeymoon 2015 년

그럼 당신은 무엇을 원하십니까-해시 또는 주문한 것!? 둘 다 결합하려면 둘 다 생성하고 그 구조 중 하나가 다른 구조를 색인화하도록하십시오. 그렇지 않으면 이것은 디자인 문제 또는 혼합 관심사에 더 가깝습니다.
cslotty

1
관심사를 혼합하는 것이 아니라 Java와 같은 언어에서 삽입 순서를 유지하는 정렬 된 맵인 LinkedHashMap과 같은 구성으로 처리되는 상당히 그럴듯한 사용 사례입니다. 그런 다음 내가 원하는 것은 둘 다 정의 된 순서대로 키를 반복하고 키를 빠르게 조회 할 수 있기를 바랍니다. @Robotic Pants의 답변은 약간 hackish하지만 거의 작동 할 것이라고 생각합니다.
mickeymoon

그게 사실이야, 미키 문, 내가 그렇게 말하려고 했어! 하지만 JSON에서는 존재하지 않습니까? 그런 다음 그러한 것을 제공하는 언어 / 메커니즘을 포함해야합니다.
cslotty

1

실제 세계에서 애플리케이션은 거의 항상 JSON으로 /에서 직렬화 / 비 직렬화되는 Java Bean 또는 도메인을 갖습니다. 이미 JSON 개체 사양이 순서를 보장하지 않으며 해당 동작에 대한 조작이 요구 사항을 정당화하지 않는다고 이미 언급했습니다. 가독성을 높이기 위해 순서를 유지해야하는 애플리케이션에서 동일한 시나리오를 사용했습니다. 표준 잭슨 방식을 사용하여 Java Bean을 JSON으로 직렬화했습니다.

Object object = getObject();  //the source java bean that needs conversion
String jsonString = new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(object);

정렬 된 요소 집합으로 json을 만들기 위해 변환에 사용한 Java Bean에서 JSON 속성 주석을 사용합니다. 아래 예 :

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({"name","phone","city","id"})
public class SampleBean implements Serializable {
    private int id;
    private String name:
    private String city;
    private String phone;

    //...standard getters and setters
}

위에서 사용 된 getObject () :

public SampleBean getObject(){
    SampleBean bean  = new SampleBean();
    bean.setId("100");
    bean.setName("SomeName");
    bean.setCity("SomeCity");
    bean.setPhone("1234567890");
    return bean;
}

출력은 Json 속성 순서 주석에 따라 표시됩니다.

{
    name: "SomeName",
    phone: "1234567890",
    city: "SomeCity",
    id: 100
}

0

가장 안전한 방법은 출력을 생성하는 데 사용되는 키 메서드를 재정의하는 것입니다.

new JSONObject(){
  @Override
  public Iterator keys(){
    TreeSet<Object> sortedKeys = new TreeSet<Object>();
    Iterator keys = super.keys();
    while(keys.hasNext()){
      sortedKeys.add(keys.next());
    }
    return sortedKeys.iterator();
  }
};

1
이것은 명시된 문제를 해결하지 못합니다. 이로 인해 키가 정렬되지만 삽입 순서를 유지할 것인지 묻는 질문이 표시됩니다.
Stephen C

0

patchFor (답변 @gary) :

$ git diff JSONObject.java                                                         
diff --git a/JSONObject.java b/JSONObject.java
index e28c9cd..e12b7a0 100755
--- a/JSONObject.java
+++ b/JSONObject.java
@@ -32,7 +32,7 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.Collection;
 import java.util.Enumeration;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
@@ -152,7 +152,9 @@ public class JSONObject {
      * Construct an empty JSONObject.
      */
     public JSONObject() {
-        this.map = new HashMap<String, Object>();
+//      this.map = new HashMap<String, Object>();
+        // I want to keep order of the given data:
+        this.map = new LinkedHashMap<String, Object>();
     }

     /**
@@ -243,7 +245,7 @@ public class JSONObject {
      * @throws JSONException
      */
     public JSONObject(Map<String, Object> map) {
-        this.map = new HashMap<String, Object>();
+        this.map = new LinkedHashMap<String, Object>();
         if (map != null) {
             Iterator<Entry<String, Object>> i = map.entrySet().iterator();
             while (i.hasNext()) {

0

다음 코드를 사용하여 JSON 배열의 사용자 지정 ORDERED 직렬화 및 역 직렬화를 수행 할 수 있습니다 (이 예제에서는 문자열을 정렬한다고 가정하지만 모든 유형에 적용 할 수 있음).

직렬화

JSONArray params = new JSONArray();
int paramIndex = 0;

for (String currParam : mParams)
{
    JSONObject paramObject = new JSONObject();
    paramObject.put("index", paramIndex);
    paramObject.put("value", currParam);

    params.put(paramObject);
    ++paramIndex;
}

json.put("orderedArray", params);

역 직렬화

JSONArray paramsJsonArray = json.optJSONArray("orderedArray");
if (null != paramsJsonArray)
{
    ArrayList<String> paramsArr = new ArrayList<>();
    for (int i = 0; i < paramsJsonArray.length(); i++)
    {
        JSONObject param = paramsJsonArray.optJSONObject(i);
        if (null != param)
        {
            int paramIndex = param.optInt("index", -1);
            String paramValue = param.optString("value", null);

            if (paramIndex > -1 && null != paramValue)
            {
                paramsArr.add(paramIndex, paramValue);
            }
        }
    }
}

0

귀하의 예 :

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
        ...
    ]
}

"itemorder"요소 추가

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
        ...
    ],
    "itemorder":["WR","QU","QA","WO","NO"]
}

이 코드는 열 제목 줄없이 원하는 출력을 생성합니다.

JSONObject output = new JSONObject(json);
JSONArray docs = output.getJSONArray("data");
JSONArray names = output.getJSONArray("itemOrder");
String csv = CDL.toString(names,docs);

이것은 지금은 행이 주문하지만 헤더없이이의 CSV의 헤더를 제거
페드로 호아킨을

0

jsonObject를 사용하는 대신 CsvSchema를 더 쉽게 사용하고 객체를 csv로 직접 변환하십시오.

CsvSchema schema = csvMapper.schemaFor(MyClass.class).withHeader();
        csvMapper.writer(schema).writeValueAsString(myClassList);

그것은 당신의 POJO가 가지고있는 주문 ID mentains @JsonPropertyOrder을 그것에을


0

Underscore-java는 json을 읽는 동안 요소의 순서를 유지합니다. 나는 프로젝트의 관리자입니다.

String json = "{\n"
      + "    \"items\":\n"
      + "    [\n"
      + "        {\n"
      + "            \"WR\":\"qwe\",\n"
      + "            \"QU\":\"asd\",\n"
      + "            \"QA\":\"end\",\n"
      + "            \"WO\":\"hasd\",\n"
      + "            \"NO\":\"qwer\"\n"
      + "        }\n"
      + "    ]\n"
      + "}";
System.out.println(U.fromJson(json));

// {items=[{WR=qwe, QU=asd, QA=end, WO=hasd, NO=qwer}]}

-1

윙크 솔루션을 테스트하고 정상적으로 작동합니다.

@Test
public void testJSONObject() {
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("bbb", "xxx");
    jsonObject.put("ccc", "xxx");
    jsonObject.put("aaa", "xxx");
    jsonObject.put("xxx", "xxx");
    System.out.println(jsonObject.toString());
    assertTrue(jsonObject.toString().startsWith("{\"xxx\":"));
}

@Test
public void testWinkJSONObject() throws JSONException {
    org.apache.wink.json4j.JSONObject jsonObject = new OrderedJSONObject();
    jsonObject.put("bbb", "xxx");
    jsonObject.put("ccc", "xxx");
    jsonObject.put("aaa", "xxx");
    jsonObject.put("xxx", "xxx");
    assertEquals("{\"bbb\":\"xxx\",\"ccc\":\"xxx\",\"aaa\":\"xxx\",\"xxx\":\"xxx\"}", jsonObject.toString());
}

Maven 종속성 : <dependency> <groupId> org.apache.wink </ groupId> <artifactId> wink-json4j </ artifactId> <version> 1.4 </ version> </ dependency>
jgpelaez

@cypressious와 같은 대답 ... 2 년 전에 게시되었습니다. 그리고 예제는 실제 가치를 추가하지 않습니다.
Stephen C
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.