2011-09-23 38 views
39

Tôi đang phát triển một giao diện RESTful được sử dụng để cung cấp dữ liệu JSON cho một ứng dụng JavaScript.Ràng buộc JSON để lồng vào các đối tượng miền Grails

Ở phía máy chủ, tôi sử dụng Grails 1.3.7 và sử dụng đối tượng tên miền GORM để duy trì. Tôi thực hiện một tùy chỉnh JSON marshaller để hỗ trợ marshalling lĩnh vực lồng đối tượng

Dưới đây là mẫu vật miền:

class SampleDomain { 
    static mapping = { nest2 cascade: 'all' } 
    String someString 
    SampleDomainNested nest2 
} 

class SampleDomainNested { 
    String someField 
} 

Nguồn SampleDomain được công bố theo URL/rs/mẫu/so/rs/sample/1 điểm đối tượng SampleDomain với ID 1

Khi tôi hiển thị tài nguyên bằng cách sử dụng trình soạn thảo json tùy chỉnh của tôi (GET on/rs/sample/1), tôi nhận được các dữ liệu sau:

{ 
    "someString" : "somevalue1", 
    "nest2" : { 
     "someField" : "someothervalue" 
    } 
} 

chính xác là những gì tôi muốn.

Hiện đã xảy ra sự cố: Tôi cố gắng gửi cùng một dữ liệu đến tài nguyên/rs/sample/1 qua PUT.

Để liên kết dữ liệu json với đối tượng miền, trình điều khiển xử lý yêu cầu gọi def domain = SampleDomain.get(id)domain.properties = data nơi dữ liệu là đối tượng chưa được sửa đổi.

Ràng buộc cho trường "someString" đang hoạt động tốt, nhưng đối tượng lồng nhau không được điền bằng cách sử dụng dữ liệu lồng nhau để tôi nhận được lỗi rằng thuộc tính "nest2" là rỗng, không được phép.

Tôi đã thử triển khai PropertyEditorSupport tùy chỉnh cũng như StructuredPropertyEditor và đăng ký trình chỉnh sửa cho lớp học.

Thật lạ, trình chỉnh sửa chỉ được gọi khi tôi cung cấp các giá trị không lồng nhau. Vì vậy, khi tôi gửi thông tin sau đến máy chủ thông qua PUT (không có ý nghĩa gì;))

{ 
    "someString" : "somevalue1", 
    "nest2" : "test" 
} 

ít nhất là trình chỉnh sửa thuộc tính được gọi.

Tôi đã xem mã số GrailsDataBinder. Tôi phát hiện ra rằng việc thiết tính chất của một hiệp hội dường như làm việc bằng cách xác định con đường của hiệp hội thay vì cung cấp một bản đồ, vì vậy các công trình sau đây cũng như:

{ 
    "someString" : "somevalue1", 
    "nest2.somefield" : "someothervalue" 
} 

nhưng điều này không giúp tôi kể từ khi tôi don' t muốn triển khai JavaScript tùy chỉnh cho trình nối tiếp đối tượng JSON.

Có thể sử dụng liên kết dữ liệu Grails bằng các bản đồ lồng nhau không? Hay tôi thực sự muốn thực hiện điều đó bằng tay cho mỗi lớp miền?

Thanks a lot,

Martin

+0

bạn cũng có một trình sửa đổi json tùy chỉnh không? – fixitagain

+0

Không, tôi không có trình chỉnh sửa json tùy chỉnh. Tôi phân tích cú pháp yêu cầu bằng cách sử dụng request.JSON. Những gì tôi muốn là một trình soạn thảo thuộc tính hỗ trợ cả việc tạo một đối tượng miền từ một Bản đồ cũng như tải/ánh xạ một đối tượng miền theo ID. – frow

+1

Bạn đã thử plugin này: http://www.grails.org/plugin/json-rest-api –

Trả lời

1

Nó đòi hỏi bạn phải cung cấp teh tên lớp:

{ class:"SampleDomain", someString: "abc", 
nest2: { class: "SampleDomainNested", someField:"def" } 
} 

tôi biết, nó đòi hỏi đầu vào khác nhau mà đầu ra nó tạo ra.

Như tôi đã đề cập trong nhận xét trước đó, bạn có thể sử dụng thư viện gson tốt hơn.

1

Không chắc chắn lý do tại sao bạn đã viết marshaller json của riêng bạn, với xstream xung quanh.

Xem http://x-stream.github.io/json-tutorial.html

Chúng tôi đã rất hài lòng với xStream cho back-end của chúng tôi dịch vụ (grails dựa) và bằng cách này bạn có thể làm cho marshall trong xml hoặc json, hoặc ghi đè lên marshalling mặc định cho một đối tượng cụ thể nếu bạn thích .

Jettison dường như tạo ra một JSON nhỏ gọn hơn có thể đọc được con người và bạn có thể chạy vào một số công cụ va chạm trong thư viện, nhưng trình kết xuất luồng nội dung json mặc định là khá.

Nếu bạn đang đi để công bố các dịch vụ cho công chúng, bạn sẽ muốn dành thời gian để trở lại phản ứng giao thức HTTP thích hợp cho các lỗi vv ... ($ .02)

7

Kể từ khi câu hỏi này đã bỏ phiếu tán nhiều thời gian tôi muốn chia sẻ những gì tôi đã làm cuối cùng:

Vì tôi đã có một số yêu cầu khác để được thực hiện như bảo mật, vv Tôi đã triển khai một lớp dịch vụ ẩn các đối tượng miền khỏi bộ điều khiển. Tôi đã giới thiệu một "lớp DTO động" dịch các đối tượng miền sang Groovy Maps có thể được tuần tự hóa dễ dàng bằng cách sử dụng các serializers chuẩn và thực hiện các cập nhật theo cách thủ công. Tất cả các giải pháp dựa trên bán tự động/meta-programming/command/... Tôi đã cố gắng triển khai thất bại tại một số điểm, phần lớn dẫn đến lỗi GORM lạ hoặc nhiều mã cấu hình (và rất nhiều thất vọng). Các phương thức cập nhật và tuần tự hóa cho các DTO khá đơn giản và có thể được thực hiện rất nhanh chóng. Nó cũng không giới thiệu nhiều mã trùng lặp vì bạn phải chỉ định cách các đối tượng miền của bạn được tuần tự hóa nếu bạn không muốn xuất bản cấu trúc đối tượng miền nội bộ của mình. Có lẽ đó không phải là giải pháp thanh lịch nhất nhưng đó là giải pháp duy nhất thực sự hiệu quả đối với tôi. Nó cũng cho phép tôi thực hiện cập nhật hàng loạt vì logic cập nhật không được kết nối với các yêu cầu http nữa.

Tuy nhiên tôi phải nói rằng tôi không nghĩ rằng grails là ngăn xếp công nghệ thích hợp phù hợp nhất cho loại ứng dụng này, vì nó làm cho ứng dụng của bạn rất nặng và nhồi. Kinh nghiệm của tôi là một khi bạn bắt đầu làm những thứ không được hỗ trợ bởi framework theo mặc định, nó bắt đầu lộn xộn. Hơn nữa, tôi không thích thực tế là lớp "kho lưu trữ" trong grails về cơ bản chỉ tồn tại như một phần của các đối tượng miền đã giới thiệu rất nhiều vấn đề và dẫn đến một số "dịch vụ proxy" mô phỏng một lớp kho lưu trữ. Nếu bạn bắt đầu xây dựng một ứng dụng bằng cách sử dụng giao diện phần còn lại của json, tôi sẽ đề xuất sử dụng công nghệ có trọng lượng rất nhẹ như node.js hoặc nếu bạn muốn/phải dính vào một ngăn xếp dựa trên java, hãy sử dụng khung công tác Spring chuẩn mùa xuân mvc + mùa xuân dữ liệu với một lớp dto đẹp và sạch sẽ (đây là những gì tôi đã di cư đến và nó hoạt động như một say mê). Bạn không cần phải viết nhiều mã soạn sẵn và bạn hoàn toàn kiểm soát được những gì đang thực sự xảy ra. Hơn nữa, bạn nhận được đánh máy mạnh mẽ làm tăng năng suất của nhà phát triển cũng như khả năng bảo trì và hợp pháp hóa các LOC bổ sung. Và tất nhiên gõ mạnh mẽ có nghĩa là dụng cụ mạnh mẽ!

Tôi bắt đầu viết một mục blog mô tả kiến ​​trúc tôi đã đưa ra (với một dự án mẫu của khóa học), tuy nhiên tôi không có nhiều thời gian để hoàn thành nó. Khi nó được thực hiện tôi sẽ liên kết với nó ở đây để tham khảo.

Hy vọng điều này có thể là nguồn cảm hứng cho những người gặp sự cố tương tự.

Chúc mừng!

+0

Cảm ơn thông tin chi tiết này, tôi thấy nó rất hữu ích. Tôi bắt đầu xây dựng một dự án với Grails gần đây, và tôi đang đi đến cùng một kết luận như bạn đã làm. Tôi chọn Grails sự hiểu biết thương mại-off, nhiều goodies và baddies. Nhưng, sự hạn chế này đối với một vật thể phức tạp không được marshalling là một bất ngờ lớn đối với tôi. Bây giờ, tôi đang có một ý nghĩ thứ hai, quay trở lại Spring MVC + Spring Data. Điều duy nhất tôi sẽ bỏ lỡ là GSP. Tôi đang tìm kiếm GSP, đặc biệt là sitemesh, rất mạnh mẽ. Bạn có biết bất kỳ công nghệ nào có thể được sử dụng với Spring MVC tốt như GSP không? –

+0

Hãy nhìn vào Thymeleaf. Nó có một mục tiêu rất giống với GSP. –

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