2012-06-06 26 views
11

Tôi muốn serialize để JSON như sau (java) cấu trúc dữ liệu:JSON Đại diện của Map với Complex chính

class Machine { 
    String name; 
    Map<PartDescriptor, Part> parts; 
} 

class PartDescriptor { 
    String group; 
    String id; 

    hashCode() 
    equals() 
} 

class Part { 
    String group; 
    String id; 
    String description; 
    String compat; 
    ... 
    ... 
} 

Điều gì sẽ là đại diện của một JSON Machine?

Ngoài (tùy chọn), chỉ cho tôi một JSON để Java serializer/deserializer rằng sẽ hỗ trợ đại diện của bạn

+1

Vì JSON là rất hạn chế trong khả năng thể hiện chi tiết loại, các serializers có mục đích chung thường gây thất vọng và không đủ cho các mục đích cụ thể. Nó có thể được dễ dàng hơn nhiều để chỉ cần thực hiện serializer của riêng bạn cho các cấu trúc dữ liệu của riêng bạn. – Pointy

+0

@Pointy Cảm ơn Pointy, tôi đã không sử dụng JSON cho mục đích này trước đây, và tôi nhận ra quan điểm của bạn. Tôi đã hỏi câu hỏi này để nghe một số ý tưởng kể từ khi tôi lãng phí vài giờ bực bội với api không có giấy tờ và kỳ lạ của apson –

Trả lời

8

Tôi muốn làm điều gì đó như:

{ 
    "name": "machine name", 
    "parts": [ 
    { "group": "part group", "id": "part id", "description": "...", ... }, 
    { "group": "part group", "id": "part id", "description": "...", ... }, 
    // ... 
    ] 
} 

Nếu "id" cho mỗi Phần là duy nhất, sau đó thuộc tính "phần" có thể là một đối tượng thay vì một mảng, với "id" của mỗi phần làm khóa.

{ 
    "name": "machine name", 
    "parts": { 
    "1st part id": { "group": "part group", "description": "...", ... }, 
    "2nd part id": { "group": "part group", "description": "...", ... }, 
    // ... 
    } 
} 
+0

Vì PartDescriptor là chìa khóa cho bản đồ java, tôi nghĩ chúng ta có thể giả định một cách an toàn rằng tổ hợp nhóm + id là duy nhất, mẫu thứ hai của bạn. –

2

Tôi sẽ làm điều này. Phím parts của đối tượng cấp cao nhất sẽ là JSONArray của JSONObjectkeyvalue. key sẽ là một đối tượng là PartDescriptor của bạn và value sẽ là Part của bạn.

{ 
    "name":"theName", 
    "parts":[ 
     { 
      "key":{ 
         "group":"theGroup", 
         "id":"theId" 
        }, 
      "value":{ 
         "group":"theGroup", 
         "id":"theId", 
         "description":"theDescription", 
         "compat":"theCompat", 
         ... 
        } 
     }, 
     ... 
    ] 
} 
1

Giả sử rằng nhóm + id cho một sự kết hợp độc đáo, và rằng ":" là một delimiter phép:

{ 
    "name": "machine name", 
    "parts": { 
       "somegroup:01465": { 
            "group":"somegroup", 
            "id": "01465", 
            ... 
            }, 
       "othergroup:32409": { 
            "group":"othergroup", 
            "id": "32409", 
            ... 
            } 

      } 
} 
-4

Nó có thể được trả lại như bảng sau:

<table class="machine" name=""> 
    <tr> 
    <th class="partdescriptor" colspan="2"> 
    <th class="part" colspan="4"> 
    </tr> 
    <tr> 
    <td class="partdescriptor group"></td> 
    <td class="partdescriptor" id=""></td> 
    <td class="part group"></td> 
    <td class="part" id=""></td> 
    <td class="description"></td> 
    <td class="compat"></td> 
    </tr> 
</table> 

Đánh dấu phân tách thành đối tượng JSON sau do thiếu siêu dữ liệu thông qua các thuộc tính:

{ 
    "HTMLTableElement": 
    [ 
     { 
      "classname": "machine", 
      "name": "" 
     }, 
     { 
      "HTMLTableRowElement": 
      [ 
       { 
        "HTMLTableCellElement": {"classname":"partdescriptor","colspan":2} 
       }, 
       { 
        "HTMLTableCellElement": {"classname":"part","colspan":4} 
       } 
      ] 
     }, 
     { 
      "HTMLTableRowElement": 
      [ 
       { 
        "HTMLTableCellElement": {"classname":"partdescriptor group"} 
       }, 
       { 
        "HTMLTableCellElement": {"classname":"partdescriptor","id":""} 
       }, 
       { 
        "HTMLTableCellElement": {"classname":"part","id":""} 
       }, 
       { 
        "HTMLTableCellElement": {"classname":"description"} 
       }, 
       { 
        "HTMLTableCellElement": {"classname":"compat"} 
       } 
      ] 
     } 
    ] 
} 

Ngoài ra, Unicode có thể đơn giản hóa việc lập bản đồ:

{"name":"","[{\u0022group\u0022:\u0022\u0022},{\u0022id\u0022:\u0022\u0022}]": 
[ 
{"group":""}, 
{"id":""}, 
{"description":""}, 
{"compat":""} 
] 
} 

Mà có thể được chuyển đổi thành chuỗi:

JSON.stringify({"name":"","[{\u0022group\u0022:\u0022\u0022},{\u0022id\u0022:\u0022\u0022}":[{"group":""},{"id":""},{"description":""},{"compat":""}]}) 

để sản xuất:

"{\"name\":\"\",\"[{\\\"group\\\":\\\"\\\"},{\\\"id\\\":\\\"\\\"}]\":[{\"group\":\"\"},{\"id\":\"\"},{\"description\":\"\"},{\"compat\":\"\"}]}" 

có thể được phân tích cú pháp:

JSON.parse("{\"name\":\"\",\"[{\\\"group\\\":\\\"\\\"},{\\\"id\\\":\\\"\\\"}]\":[{\"group\":\"\"},{\"id\":\"\"},{\"description\":\"\"},{\"compat\":\"\"}]}") 

để tạo ra một đối tượng theo nghĩa đen:

Tài liệu tham khảo

8

Bạn không cần ANNOT hành hoặc serializers tùy chỉnh.Giả sử bạn đã có getters cho tất cả các trường trong PartMachine, tất cả những gì thực sự bị thiếu là toString() trên PartDescriptor. Nếu vì một lý do nào đó, bạn không có chức năng getter, bạn sẽ cần chú thích các trường cần quan tâm với @JsonProperty để Jackson biết trường nào cần đưa vào đầu ra tuần tự. Tuy nhiên, nó là thích hợp hơn (và dễ dàng hơn) để chỉ cần tạo ra getters.

toString() trên PartDescriptor phải trả lại khóa bạn muốn sử dụng trong ánh xạ của mình. Như câu trả lời khác cho thấy, bạn có thể chỉ đơn giản là nối các lĩnh vực có liên quan:

@Override 
public String toString() { 
    return group + "|" + id; 
} 

Sau đó, bạn sẽ kỳ diệu lấy mẫu này khi bạn cố gắng để serialize một Machine với của Jackson ObjectMapper:

{ 
    "name" : "Toaster", 
    "parts" : { 
    "Electrical|Descriptor1" : { 
     "group" : "Electrical", 
     "id" : "Part1", 
     "description" : "Heating Element", 
     "compat" : "B293" 
    }, 
    "Exterior|Descriptor2" : { 
     "group" : "Exterior", 
     "id" : "Part2", 
     "description" : "Lever", 
     "compat" : "18A" 
    } 
    } 
} 
+0

Kết quả là một đối tượng JavaScript theo nghĩa đen, nhưng không phải là đối tượng JSON –

+0

@PaulSweatte Ý của bạn là gì? Đây là [JSON hợp lệ] (http://jsonlint.com/). Trên thực tế, tất cả JSON ** là ** đối tượng JavaScript theo nghĩa đen ... – user113215

+0

Xin lỗi, sao chép/dán mã của bạn bị mất dấu ngoặc đơn. Cú pháp JSON hạn chế hơn cú pháp ngữ pháp đối tượng. Ví dụ, không có bình luận hoặc dấu nháy đơn nào được phép, và các tên khóa phải được trích dẫn. –

Các vấn đề liên quan