2011-01-27 27 views
13

Tôi đang sử dụng thư viện jackson để serializing/deserializing đến/từ JSON. Tôi cần JSON này có kích thước nhỏ nhất có thể nên tôi đã bật tính năng ALLOW_UNQUOTED_FIELD_NAMES để loại bỏ tất cả các dấu ngoặc kép. Tôi biết rằng việc loại bỏ các trích dẫn không phải là tiêu chuẩn json, nhưng làm cho json nhỏ là một yêu cầu khó khăn của dự án. Các json tạo ra hoạt động, nhưng khi tôi đã cố gắng để đọc các giá trị json tôi nhận được một ngoại lệ:ALLOW_UNQUOTED_FIELD_NAMES trong jackon Thư viện JSON

org.codehaus.jackson.JsonParseException: nhân vật bất ngờ ('9' (mã 57)): đang mong đợi tên hợp lệ ký tự (đối với tên không được bỏ phiếu) hoặc báo giá kép (để được trích dẫn) để bắt đầu tên trường tại [Nguồn: [email protected]; dòng: 1, cột: 3]

Trường hợp ngoại lệ trên được ném khi tôi đọc json này:

{90110a2e-febd-470f-afa4-cf7e890d31b9:0,eec652ad-a4d9-4eb1-8d24-7c1a0c29449f:1} 

Con đường tôi đọc nó là:

Map<String, Object> valuesMap = oM.readValue(json, new TypeReference<Map<String, Object>>() {}); 

và đối tượng người lập bản đồ tôi sử dụng cả để đọc và viết các giá trị là:

private static final ObjectMapper om = new ObjectMapper(); 
static { 
    om.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false); 
    om.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); 
    om.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, true); 
    om.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); 
    om.getSerializationConfig().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL); 
} 

Tôi đang sử dụng phiên bản 1.6.3 của Jackson, trong cả dự án người gửi và người nhận. Phiên bản cần thiết cho tính năng này là 1,2+ vì vậy tôi nghĩ rằng có lẽ tôi đã không sử dụng phiên bản này, nhưng người nhận của tôi là một ứng dụng Spring và tôi đã kiểm tra thư viện được cài đặt trong thư mục libs là 1.6.3.

Tôi có thể làm gì sai? Có thể không sử dụng tính năng này với bản đồ.

Tôi có một câu hỏi khác, Cho đến nay tôi chỉ gửi một bản đồ trong đó khóa chỉ là giá trị uuid và giá trị là một số. Tôi có thể gặp bất kỳ sự cố nào nếu tôi gửi một giá trị có các ký tự đặc biệt với tính năng ALLOW_UNQUOTED_FIELD_NAMES không? Jackson sẽ thoát khỏi nhân vật này?

Cảm ơn.

Trả lời

5

Dường như Jackson có QUOTE_FIELD_NAMES trong một số trường hợp nhất định tạo ra kết quả đầu ra như vậy mà không thể đọc chính nó ngay cả với ALLOW_UNQUOTED_FIELD_NAMES bật. Có thể bạn sẽ cần triển khai tùy chỉnh JsonParser để phân tích cú pháp đầu vào không chuẩn.

Vấn đề là bạn đang tạo JSON không chuẩn và không có đảm bảo rằng khách hàng sẽ xử lý đúng cách. Tuy nhiên, nếu bạn không tiết lộ nó bên ngoài ứng dụng của bạn (s) và quan tâm về kích thước nhiều bạn có thể phân tích/tạo ra định dạng nhị phân như của Jackson Smile. Xem http://www.cowtowncoder.com/blog/archives/2010/09/entry_418.html (2.4).

+0

Điểm rất tốt về Smile - nó có thể nhỏ gọn, đặc biệt. khi bật tham chiếu ngược giá trị chuỗi (nếu có nhiều giá trị chuỗi lặp lại, như giá trị được liệt kê) – StaxMan

2

Tôi tin rằng sự cố có liên quan đến sintax Javascript chứ không phải với Jackson cũng như JSON.

Trong Javascript, tên là một chữ cái được theo sau bởi một hoặc nhiều chữ cái, chữ số hoặc gạch dưới, vì vậy 90110a2e-febd-470f-afa4-cf7e890d31b9 không phải là tên Javascript hợp pháp.

Dấu ngoặc kép xung quanh tên của thuộc tính là tùy chọn nếu tên đó là tên JavaScript hợp pháp và không phải là từ dành riêng. Vì vậy, báo giá được yêu cầu xung quanh "tên đầu tiên", nhưng là tùy chọn xung quanh first_name.

BTW, nếu bạn quan tâm đến kích thước JSON tại sao bạn không gzip nó?

+0

Cảm ơn tôi đã nghĩ về nó nhưng tôi không chắc liệu các biến đó có hợp pháp hay không. Mặc dù json không được sử dụng trong javascript (nó được gửi từ một máy khách Java đến một ứng dụng JEE) những gì bạn nói có thể đúng. Đối với gzip, tôi đã gửi các json nén, nhưng cảm ơn cho ý tưởng anyway. – Javi

6

Ok, câu trả lời của Pingw33n là khá chính xác, tôi nghĩ vậy. Vì vậy: có, bạn có thể sử dụng tính năng này; nhưng nó là khá heuristic - vì không có đặc điểm kỹ thuật như thế nào unquoted tên nên làm việc (sau khi tất cả, JSON cho phép bất kỳ và tất cả các ký tự cho tên!); hoặc, nếu cơ chế trốn thoát nào được sử dụng, thì có ai đó đoán được điều gì nên được viết hoặc chấp nhận.

Trong trường hợp cụ thể này, đó có thể là ký tự '-' gây ra sự cố. Nó không phải là một phần hợp pháp của tên Javascript, đó là xấp xỉ Jackson sử dụng.

Một giải pháp có thể là để Jackson thoát khỏi các ký tự như vậy trong tên thuộc tính (Tôi không nhớ nó được thực hiện như thế nào, nếu có ký tự tên được trích dẫn). Nếu bạn có thể tìm ra một trường hợp thử nghiệm đơn giản, bạn có thể gửi yêu cầu Jira-for-enchancement tại số Jackson Jira để thoát khỏi việc thêm (và đảm bảo trình phân tích cú pháp có thể gỡ bỏ phiên bản dấu gạch chéo ngược thông thường).

+1

Ồ. Trên thực tế, nó thậm chí còn đơn giản hơn thế: vì mã định danh javascript không thể bắt đầu bằng số, đó là nguyên nhân gây ra sự cố. Cũng có thể thư giãn điều này, cho chế độ ALLOW_UNQUOTED_FIELD_NAMES; cho yêu cầu tính năng Jira này sẽ giúp ích. – StaxMan

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