Khi nào tôi nên sử dụng RequestFactory so với GWT-RPC?


87

Tôi đang cố gắng tìm hiểu xem liệu tôi có nên di chuyển các lệnh gọi gwt-rpc của mình sang các cals RequestFactory GWT2.1 mới hay không.

Tài liệu của Google đề cập một cách mơ hồ rằng RequestFactory là một phương thức giao tiếp máy khách-máy chủ tốt hơn cho "dịch vụ hướng dữ liệu"

Những gì tôi có thể chắt lọc từ tài liệu là có một lớp Proxy mới giúp đơn giản hóa giao tiếp (bạn không chuyển qua lại thực thể thực mà chỉ là proxy, vì vậy nó nhẹ hơn và dễ quản lý hơn)

Đó là toàn bộ vấn đề hay tôi đang bỏ lỡ điều gì khác trong bức tranh lớn?


8
yay, câu hỏi này được liên kết từ hướng dẫn viên gwt chính thức !
törzsmókus

Câu trả lời:


73

Sự khác biệt lớn giữa GWT RPC và RequestFactory là hệ thống RPC là "RPC-by-specific-type" trong khi RequestFactory là "RPC-by-interface".

RPC thuận tiện hơn để bắt đầu, vì bạn viết ít dòng mã hơn và sử dụng cùng một lớp trên cả máy khách và máy chủ. Bạn có thể tạo một Personlớp với một loạt các getters và setters và có thể là một số logic nghiệp vụ đơn giản để cắt và phân tích dữ liệu trong Personđối tượng. Điều này hoạt động khá tốt cho đến khi bạn muốn có mã dành riêng cho máy chủ, không tương thích với GWT, bên trong lớp của mình. Vì hệ thống RPC dựa trên việc có cùng một loại cụ thể trên cả máy khách và máy chủ, bạn có thể gặp phải một bức tường phức tạp dựa trên khả năng của máy khách GWT của bạn.

Để tránh sử dụng mã không tương thích, nhiều người dùng đã tạo ra một đồng đẳng PersonDTOlàm bóng Personđối tượng thực được sử dụng trên máy chủ. Các PersonDTOchỉ có một tập hợp con của getter và setter của server-side, "miền", Personđối tượng. Bây giờ bạn phải viết mã mà Marshalls dữ liệu giữa PersonPersonDTOđối tượng và tất cả các loại đối tượng khác mà bạn muốn chuyển cho khách hàng.

RequestFactory bắt đầu bằng cách giả định rằng các đối tượng miền của bạn sẽ không tương thích với GWT. Bạn chỉ cần khai báo các thuộc tính sẽ được đọc và viết bởi mã máy khách trong giao diện Proxy, và các thành phần máy chủ RequestFactory đảm nhận việc sắp xếp dữ liệu và gọi các phương thức dịch vụ của bạn. Đối với các ứng dụng có khái niệm được xác định rõ ràng về "Thực thể" hoặc "Đối tượng có danh tính và phiên bản", EntityProxyloại được sử dụng để hiển thị ngữ nghĩa nhận dạng liên tục của dữ liệu của bạn với mã máy khách. Các đối tượng đơn giản được ánh xạ bằng cách sử dụng ValueProxykiểu.

Với RequestFactory, bạn phải trả chi phí khởi động trước để đáp ứng các hệ thống phức tạp hơn GWT RPC dễ dàng hỗ trợ. RequestFactory's ServiceLayercung cấp nhiều móc hơn đáng kể để tùy chỉnh hành vi của nó bằng cách thêm các ServiceLayerDecoratorphiên bản.


Đây là lý do chính đáng để ủng hộ quyết định chuyển sang RequestFactory của tôi. Cảm ơn bạn, Bob! Nó có lý và tôi không hiểu tại sao một số người nói "sử dụng RPC trong một số trường hợp và RF trong những trường hợp khác tùy thuộc vào nhu cầu của bạn" vì có vẻ như với RPC bạn phải viết rất nhiều mã keo và lớp DTO đó
Dan L.

5
Một điểm cộng cho RequestFactory là nó có thể được sử dụng với Android và GWT với cùng một mã chính xác.
Patrick

28

Tôi đã trải qua quá trình chuyển đổi từ RPC sang RF. Đầu tiên, tôi phải nói rằng kinh nghiệm của tôi có hạn, tôi đã sử dụng nhiều EntityProxies bằng 0.

Ưu điểm của GWT RPC:

  • Nó rất dễ cài đặt, hiểu và HỌC!
  • Các đối tượng dựa trên cùng một lớp được sử dụng trên máy khách và trên máy chủ.
  • Cách tiếp cận này tiết kiệm rất nhiều mã.
  • Lý tưởng là khi các đối tượng mô hình giống nhau (và POJOS) được sử dụng trên máy khách và máy chủ, POJOs == ĐỐI TƯỢNG MÔ HÌNH == DTOs
  • Dễ dàng di chuyển nội dung từ máy chủ đến máy khách.
  • Dễ dàng chia sẻ việc thực hiện logic chung giữa máy khách và máy chủ (điều này có thể trở thành một bất lợi quan trọng khi bạn cần một logic khác).

Những khuyết điểm của GWT RPC:

  • Không thể có cách triển khai khác nhau của một số phương pháp cho máy chủ và máy khách, ví dụ: bạn có thể cần sử dụng khung ghi nhật ký khác nhau trên máy khách và máy chủ, hoặc phương pháp bằng khác nhau.
  • Thực sự BAD triển khai không thể mở rộng thêm: hầu hết các chức năng của máy chủ được triển khai dưới dạng các phương thức tĩnh trên một lớp RPC. ĐIỀU ĐÓ THỰC SỰ HẤP DẪN.
  • ví dụ: Không thể thêm sự xáo trộn lỗi phía máy chủ
  • Một số lo ngại về XSS bảo mật không được giải quyết một cách tinh tế, hãy xem tài liệu (Tôi không chắc liệu điều này có thanh lịch hơn cho RequestFactory hay không)

Nhược điểm của RequestFactory:

  • THỰC SỰ CỨ hiểu được từ tài liệu chính thức, điều đáng mừng của nó là gì! Nó bắt đầu ngay từ thuật ngữ PROXIES hoàn toàn gây hiểu lầm - đây thực sự là DTO của RF được RF tự động tạo ra. Proxy được xác định bởi các giao diện, ví dụ: @ProxyFor (Journal.class). IDE kiểm tra xem có tồn tại các phương thức tương ứng trên Tạp chí hay không. Rất nhiều cho việc lập bản đồ.
  • RF sẽ không làm được gì nhiều cho bạn về điểm chung của máy khách và máy chủ vì
  • Trên máy khách, bạn cần chuyển đổi "PROXIES" thành các đối tượng miền máy khách và ngược lại. Điều này hoàn toàn vô lý. Nó có thể được thực hiện trong vài dòng mã một cách khai báo, nhưng KHÔNG CÓ SỰ HỖ TRỢ CHO ĐIỀU ĐÓ! Giá như chúng ta có thể ánh xạ các đối tượng miền của mình với proxy một cách thanh lịch hơn, một cái gì đó như phương thức JavaScript JSON.stringify (.. ,,) đang MISSING trong hộp công cụ RF.
  • Đừng quên rằng bạn cũng chịu trách nhiệm thiết lập các thuộc tính có thể chuyển nhượng của các đối tượng miền của bạn thành proxy, v.v. một cách đệ quy.
  • XỬ LÝ LỖI NGHÈO trên máy chủ và - Dấu vết ngăn xếp được bỏ qua theo mặc định trên máy chủ và bạn đang nhận được các ngoại lệ vô ích trống trên máy khách. Ngay cả khi tôi đặt trình xử lý lỗi tùy chỉnh, tôi vẫn không thể truy cập dấu vết ngăn xếp cấp thấp! Khủng khiếp.
  • Một số lỗi nhỏ trong hỗ trợ IDE và các nơi khác. Tôi đã gửi hai yêu cầu lỗi đã được chấp nhận. Không cần phải có một Einstein để nhận ra rằng đó thực sự là những con bọ.
  • TÀI LIỆU SUCKS. Như tôi đã đề cập đến proxy nên được giải thích rõ hơn, thuật ngữ này là MISLEADING. Đối với các vấn đề chung cơ bản mà tôi đang giải quyết, DOCS LÀ HỮU ÍCH. Một ví dụ khác về sự hiểu nhầm từ DOC là kết nối các chú thích của JPA với RF. Có vẻ như từ các tài liệu ngắn gọn mà họ chơi cùng nhau và vâng, có một câu hỏi tương ứng trên StackOverflow. Tôi khuyên bạn nên quên bất kỳ 'kết nối' JPA nào trước khi hiểu RF.

Ưu điểm của RequestFactory

  • Hỗ trợ diễn đàn tuyệt vời.
  • Hỗ trợ IDE khá tốt (nhưng không phải là một lợi thế so với RPC)
  • Tính linh hoạt của việc triển khai máy khách và máy chủ của bạn (khớp nối lỏng lẻo)
  • Nội dung thú vị, được kết nối với EntityProxies, ngoài DTO đơn giản - bộ nhớ đệm, cập nhật từng phần, rất hữu ích cho thiết bị di động.
  • Bạn có thể sử dụng ValueProxies để thay thế đơn giản nhất cho DTO (nhưng bạn phải tự mình thực hiện tất cả các chuyển đổi không quá cầu kỳ).
  • Hỗ trợ xác thực Bean JSR-303.

Xem xét các nhược điểm khác của GWT nói chung:

  • Không thể chạy các bài kiểm tra tích hợp (mã máy khách GWT + máy chủ từ xa) với hỗ trợ JUnit được cung cấp <= tất cả JSNI phải được chế tạo (ví dụ: localStorage), SOP là một vấn đề.

  • Không hỗ trợ thiết lập thử nghiệm - trình duyệt không đầu + máy chủ từ xa <= không có thử nghiệm không đầu đơn giản cho GWT, SOP.

  • Có, có thể chạy các bài kiểm tra tích hợp selen (nhưng đó không phải là điều tôi muốn)

  • JSNI rất mạnh mẽ, nhưng tại những cuộc nói chuyện bóng bẩy mà họ đưa ra tại các hội nghị, họ không nói nhiều về việc viết mã JSNI cũng có một số quy tắc. Một lần nữa, tìm ra cách viết một lệnh gọi lại đơn giản là một nhiệm vụ đáng có của một nhà nghiên cứu thực thụ.

Tóm lại, việc chuyển đổi từ GWT RPC sang RequestFactory khác xa với tình huống WIN-WIN, khi RPC hầu như phù hợp với nhu cầu của bạn. Bạn kết thúc việc viết hàng tấn chuyển đổi từ các đối tượng miền khách hàng sang proxy và ngược lại. Nhưng bạn nhận được một số tính linh hoạt và mạnh mẽ của giải pháp của mình. Và hỗ trợ trên diễn đàn là tuyệt vời, vào thứ bảy!

Xem xét tất cả các ưu điểm và nhược điểm mà tôi vừa đề cập, việc suy nghĩ trước liệu có thực sự mang lại sự cải tiến cho giải pháp và thiết lập phát triển của bạn mà không phải đánh đổi lớn hay không.


Kiểm tra JBoss Erai. Tôi thích cách tiếp cận của họ đối với RPC.
Καrτhικ

6

Tôi thấy ý tưởng tạo các lớp Proxy cho tất cả các thực thể của mình khá khó chịu. Các pojos Hibernate / JPA của tôi được tạo tự động từ mô hình cơ sở dữ liệu. Tại sao bây giờ tôi cần tạo một bản sao thứ hai của những cái đó cho RPC? Chúng tôi có một khuôn khổ "estivation" tốt để chăm sóc "de-hiberging" cho pojos.

Ngoài ra, ý tưởng xác định các giao diện dịch vụ không hoàn toàn triển khai dịch vụ phía máy chủ như một hợp đồng java nhưng thực hiện các phương thức - với tôi nghe có vẻ rất giống J2EE 1.x / 2.x.


5
Điều đó thật khó chịu, nhưng nếu bạn vẫn phải tạo proxy, thì bạn muốn có thêm sự trợ giúp mà RF cung cấp cho bạn để quản lý những proxy đó. Không phải ai cũng muốn gửi toàn bộ pojo cho khách hàng - ví dụ: hãy xem xét một trò chơi poker - đối tượng Người chơi của bạn có thể có thông tin mà mọi người sẽ thấy (số quân bài trong tay, quân bài đang ngửa, tổng số chip) và các thông tin khác mà chỉ một người chơi sẽ thấy (úp các lá bài xuống).
Peter Recore

Ví dụ về Poker của bạn là hợp lệ - chúng tôi giải quyết vấn đề đó bằng cách có các chú thích (@WireTransient) mà khung "estivation" của chúng tôi sử dụng để loại bỏ các giá trị.
Καrτhικ

4

Không giống như RequestFactory có khả năng xử lý lỗi và kiểm tra kém (vì nó xử lý hầu hết các nội dung dưới lớp vỏ của GWT), RPC cho phép bạn sử dụng phương pháp tiếp cận theo hướng dịch vụ hơn. RequestFactory triển khai một cách tiếp cận theo kiểu tiêm phụ thuộc hiện đại hơn có thể cung cấp một cách tiếp cận hữu ích nếu bạn cần gọi các cấu trúc dữ liệu đa hình phức tạp. Khi sử dụng RPC, cấu trúc dữ liệu của bạn sẽ cần phải phẳng hơn, vì điều này sẽ cho phép các tiện ích sắp xếp của bạn dịch giữa các mô hình json / xml và java của bạn. Sử dụng RPC cũng cho phép bạn triển khai kiến ​​trúc mạnh mẽ hơn, như được trích dẫn từ phần gwt dev trên trang web của Google.

"Triển khai Máy khách / Máy chủ đơn giản

Cách đầu tiên và đơn giản nhất để nghĩ về các định nghĩa dịch vụ là coi chúng như là toàn bộ phần sau của ứng dụng của bạn. Từ quan điểm này, mã phía máy khách là "giao diện người dùng" của bạn và tất cả mã dịch vụ chạy trên máy chủ là "giao diện người dùng". Nếu bạn thực hiện phương pháp này, các triển khai dịch vụ của bạn sẽ có xu hướng là các API có mục đích chung hơn không được kết hợp chặt chẽ với một ứng dụng cụ thể. Các định nghĩa dịch vụ của bạn có thể sẽ truy cập trực tiếp vào cơ sở dữ liệu thông qua JDBC hoặc Hibernate hoặc thậm chí các tệp trong hệ thống tệp của máy chủ. Đối với nhiều ứng dụng, chế độ xem này là phù hợp và nó có thể rất hiệu quả vì nó làm giảm số lượng cấp.

Triển khai nhiều tầng

Trong các kiến ​​trúc nhiều tầng, phức tạp hơn, các định nghĩa dịch vụ GWT của bạn có thể chỉ đơn giản là các cổng nhẹ gọi đến các môi trường máy chủ back-end như máy chủ J2EE. Từ góc độ này, các dịch vụ của bạn có thể được xem như "một nửa máy chủ" của giao diện người dùng ứng dụng của bạn. Thay vì có mục đích chung, các dịch vụ được tạo ra cho các nhu cầu cụ thể của giao diện người dùng của bạn. Các dịch vụ của bạn trở thành "giao diện người dùng" cho các lớp "kết thúc phía sau" được viết bằng cách kết hợp các lệnh gọi tới lớp dịch vụ kết thúc có mục đích chung hơn, được thực hiện, chẳng hạn như một cụm máy chủ J2EE. Loại kiến ​​trúc này phù hợp nếu bạn yêu cầu các dịch vụ back-end của mình chạy trên một máy tính vật lý riêng biệt với máy chủ HTTP của bạn. "

Cũng lưu ý rằng việc thiết lập một dịch vụ RequestFactory yêu cầu tạo khoảng 6 lớp java hoặc lâu hơn, trong đó RPC chỉ yêu cầu 3. Nhiều mã hơn == nhiều lỗi và phức tạp hơn trong sách của tôi.

RequestFactory cũng có chi phí cao hơn một chút trong quá trình xử lý yêu cầu, vì nó phải điều khiển tuần tự hóa giữa proxy dữ liệu và các mô hình java thực tế. Giao diện bổ sung này bổ sung thêm các chu trình xử lý có thể thực sự cộng dồn trong môi trường doanh nghiệp hoặc sản xuất.

Tôi cũng không tin rằng các dịch vụ RequestFactory đang tuần tự hóa như các dịch vụ RPC.

Nói chung, sau khi sử dụng cả hai một thời gian, tôi luôn sử dụng RPC vì nó nhẹ hơn, dễ kiểm tra và gỡ lỗi hơn, và nhanh hơn khi sử dụng RequestFactory. Mặc dù RequestFactory có thể thanh lịch hơn và có thể mở rộng hơn nhưng phần truy cập RPC của nó. Sự phức tạp thêm vào không làm cho nó trở thành một công cụ tốt hơn cần thiết.

Ý kiến ​​của tôi là kiến ​​trúc tốt nhất là sử dụng hai ứng dụng web, một máy khách và một máy chủ. Máy chủ là một ứng dụng web java chung chung nhẹ đơn giản sử dụng thư viện servlet.jar. Khách hàng là GWT. Bạn thực hiện yêu cầu RESTful thông qua GWT-RPC vào phía máy chủ của ứng dụng web máy khách. Phía máy chủ của máy khách chỉ là một đường truyền đến máy khách apache http sử dụng một đường hầm liên tục vào trình xử lý yêu cầu mà bạn đang chạy dưới dạng một servlet duy nhất trong ứng dụng web servlet máy chủ của bạn. Ứng dụng web servlet nên chứa lớp ứng dụng cơ sở dữ liệu của bạn (ngủ đông, cayenne, sql, v.v.) Điều này cho phép bạn tách biệt hoàn toàn các mô hình đối tượng cơ sở dữ liệu khỏi máy khách thực tế, cung cấp một cách mở rộng và mạnh mẽ hơn nhiều để phát triển và đơn vị kiểm tra ứng dụng của bạn. Được cho là nó yêu cầu một chút thời gian thiết lập ban đầu, nhưng cuối cùng cho phép bạn tạo một nhà máy yêu cầu động bên ngoài GWT. Điều này cho phép bạn tận dụng những gì tốt nhất của cả hai thế giới. Chưa kể có thể kiểm tra và thực hiện các thay đổi đối với phía máy chủ của bạn mà không cần phải có ứng dụng khách gwt được biên dịch hoặc xây dựng.


0

Tôi nghĩ nó thực sự hữu ích nếu bạn có một pojo nặng ở phía máy khách, chẳng hạn như nếu bạn sử dụng các thực thể Hibernate hoặc JPA. Chúng tôi đã áp dụng một giải pháp khác, sử dụng khung bền vững kiểu Django với các thực thể rất nhẹ.


0

Cảnh báo duy nhất mà tôi sẽ đưa ra là RequestFactory sử dụng truyền dữ liệu nhị phân (có thể là deRPC?) Chứ không phải GWT-RPC thông thường.

Điều này chỉ quan trọng nếu bạn đang thực hiện thử nghiệm nặng với SyncProxy, Jmeter, Fiddler hoặc bất kỳ công cụ tương tự nào có thể đọc / đánh giá nội dung của yêu cầu / phản hồi HTTP (như GWT-RPC), nhưng sẽ khó khăn hơn với deRPC hoặc RequestFactory.


1
Ngoại trừ việc thực sự RequestFactory cung cấp triển khai "thuần Java" mà không cần các công cụ của bên thứ 3 như SyncProxy. Xem stackoverflow.com/questions/4853188/…
Thomas Broyer

0

Chúng tôi đã triển khai rất lớn GWT-RPC trong dự án của mình. Trên thực tế, chúng tôi có 50 giao diện Dịch vụ với nhiều phương thức, mỗi giao diện và chúng tôi gặp vấn đề với kích thước của TypeSerializers do trình biên dịch tạo ra khiến mã JS của chúng tôi rất lớn. Vì vậy, chúng tôi đang chuyển hướng sang RequestFactory. Tôi đã đọc được vài ngày khi đào sâu vào trang web và cố gắng tìm xem những người khác đang làm gì. Hạn chế quan trọng nhất mà tôi thấy, và có thể tôi đã nhầm, là với RequestFactory, bạn không còn kiểm soát được giao tiếp giữa các đối tượng Miền máy chủ và các đối tượng máy khách của bạn. Những gì chúng ta cần là áp dụng mô hình tải / lưu một cách có kiểm soát. Ý tôi là, ví dụ: khách hàng nhận được toàn bộ biểu đồ đối tượng của các đối tượng thuộc một giao dịch cụ thể, thực hiện cập nhật của mình và chúng gửi toàn bộ trở lại máy chủ. Máy chủ sẽ chịu trách nhiệm thực hiện xác nhận, so sánh giá trị cũ với giá trị mới và thực hiện duy trì. Nếu 2 người dùng từ các trang web khác nhau nhận được cùng một giao dịch và thực hiện một số cập nhật, giao dịch kết quả không nên là giao dịch được hợp nhất. Một trong những bản cập nhật sẽ không thành công trong kịch bản của tôi. Tôi không thấy rằng RequestFactory giúp hỗ trợ loại xử lý này.

Trân trọng Daniel


Tôi chia sẻ những lo lắng này ... bạn đã kết thúc với RF?
HDave

0

Có công bằng khi nói rằng khi xem xét một ứng dụng MIS giới hạn, giả sử với 10-20 đối tượng kinh doanh CRUD'able và mỗi đối tượng có ~ 1-10 thuộc tính, điều đó thực sự phụ thuộc vào sở thích cá nhân nên đi theo con đường nào?

Nếu vậy, có lẽ việc dự đoán ứng dụng của bạn sẽ mở rộng như thế nào có thể là chìa khóa trong việc chọn lộ trình GWT RPC hoặc RequestFactory của bạn:

  1. Ứng dụng của tôi dự kiến ​​sẽ ở lại với số lượng thực thể tương đối hạn chế đó nhưng sẽ tăng ồ ạt về số lượng của chúng. 10-20 đối tượng * 100.000 bản ghi.

  2. Ứng dụng của tôi sẽ tăng đáng kể về bề rộng của các thực thể nhưng số lượng tương đối liên quan của mỗi thực thể sẽ vẫn thấp. 5000 đối tượng * 100 bản ghi.

  3. Ứng dụng của tôi dự kiến ​​sẽ ở lại với số lượng thực thể tương đối hạn chế VÀ sẽ ở số lượng tương đối thấp, ví dụ: 10-20 đối tượng * 100 bản ghi

Trong trường hợp của tôi, tôi đang ở điểm bắt đầu cố gắng đưa ra quyết định này. Phức tạp hơn nữa do phải thay đổi kiến ​​trúc phía máy khách giao diện người dùng cũng như thực hiện lựa chọn truyền tải. Giao diện người dùng GWT quy mô lớn (đáng kể) trước đây của tôi đã sử dụng thư viện Hmvc4Gwt, đã được thay thế bởi các cơ sở GWT MVP.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.