2015-01-02 27 views
6

Tôi có hai ứng dụng, một ứng dụng được gọi là thanh, những gì cung cấp cho tôi tài nguyên ở định dạng HAL. Người kia là bcm để sử dụng dịch vụ đó.Tiêu thụ dịch vụ nghỉ ngơi mùa xuân Hateoas với RestTemplate

Ví dụ về phản ứng thanh trông như thế này:

[ 
    { 
     "name":"Brenner/in", 
     "_links":{ 
      "self":{ 
       "href":"..host/bbsng-app-rest/betrieb/15" 
      } 
     } 
    }, 
    { 
     "name":"Dienstleistungshelfer/in HW", 
     "_links":{ 
      "self":{ 
       "href":"..host/bbsng-app-rest/betrieb/4" 
      } 
     } 
    }, 
    { 
     ... 

Bây giờ tôi cố gắng để tiêu thụ mà từ tỷ mét khối sử dụng Spring RestTemplate. Giải pháp của tôi hoạt động, nhưng tôi không hài lòng với giải pháp đó bằng cách nào đó và tôi đoán có một cách sạch sẽ hơn.

My Client-Mã tốn RestService trông giống như:

@Autowired private RestTemplate template; 

@Override 
@SuppressWarnings("unchecked") 
public BerufListe findeAlleBerufe() { 
    final BerufListe berufListe = new BerufListe(); 

    final ResponseEntity<List> entity = template.getForEntity(LinkUtils.findBeruf(), List.class); 

    if (OK.equals(entity.getStatusCode())) { 
     final List<LinkedHashMap> body = entity.getBody(); 
     for (final LinkedHashMap map : body) { 
      final LinkedHashMap idMap = (LinkedHashMap) map.get("_links"); 
      String id = remove(String.valueOf(idMap.get("self")), "href="); 
      id = remove(id, "{"); 
      id = remove(id, "}"); 
      final String name = String.valueOf(map.get("name")); 
      final Beruf beruf = new Beruf(id, name); 
      berufListe.add(beruf); 
     } 
    } 

    return berufListe; 
} 

Có rất ít mã xấu xí như bạn thấy. Một trong số đó là, tôi không có bất kỳ generics cho bộ sưu tập của tôi. Điểm khác, tôi nhận được Resource_ID rất phức tạp, và tôi sử dụng StringUtils.remove nhiều lần để trích xuất các url tự.

Tôi chắc chắn phải có cách thuận tiện hơn để tiêu thụ Phản hồi HAL vào Mùa xuân.

Cảm ơn bạn.

Trả lời

3

Hãy xem lớp học Resource từ mùa xuân-hateaos.

Nó cung cấp các phương pháp trích xuất các liên kết từ phản hồi. Tuy nhiên, vì RestTemplate yêu cầu bạn cung cấp lớp như biến, tôi đã không tìm thấy một cách khác ngoài việc tạo một lớp con của thực thể mong muốn và sử dụng nó cho RestTemplate.

Bạn mã sau đó có thể trông như thế này:

public class BerufResource extends Resource<Beruf> { } 

BerufResource resource = template.getForEntity("http://example.at/berufe/1", BerufResource.class); 
Beruf beruf = resource.getContent(); 
// do something with the entity 

Nếu bạn muốn yêu cầu một danh sách đầy đủ, bạn sẽ cần phải vượt qua phiên bản mảng của tổ chức của bạn để RestTemplate:

BerufResource[] resources = template.getForEntity("http://example.at/berufe", BerufResource[].class); 

List<BerufResource> berufResources = Arrays.asList(resources); 
for(BerufResource resource : berufResources) { 
    Beruf beruf = resource.getContent(); 
} 

Thật không may , chúng ta không thể viết Resource<Beruf>.class mà đánh bại toàn bộ mục đích của lớp chung, vì chúng ta cần phải tạo lại một lớp con cho mọi thực thể. Lý do đằng sau đó được gọi là loại tẩy xoá. Tôi đã đọc ở đâu đó rằng họ đang có kế hoạch để giới thiệu hỗ trợ chung cho RestTemplate nhưng tôi không biết bất kỳ chi tiết nào.

Phát biểu khai thác các id từ url:

tôi sẽ khuyên bạn nên sử dụng một mô hình khác nhau trên các mặt hàng và thay thế các loại lĩnh vực id với chuỗi và lưu trữ toàn bộ url trong đó. Bằng cách này, bạn có thể dễ dàng tìm nạp lại toàn bộ thực thể bất cứ khi nào bạn muốn và không cần tự xây dựng URL. Bạn sẽ cần URL sau này, nếu bạn dự định gửi yêu cầu POST tới API của mình, vì spring-hateaos yêu cầu bạn gửi liên kết thay vì id. Một yêu cầu POST điển hình có thể trông giống như sau:

{ 
    "firstname": "Thomas", 
    "nachname": "Maier", 
    "profession": "http://example.at/professions/1" 
} 
+0

Mọi cập nhật với các bản phát hành gần đây cho câu trả lời này? – Snekse

+0

Thật không may là không. Nhưng tôi cũng đã không thực hiện nhiều nghiên cứu kể từ đó. –

+2

Bạn có thể sử dụng 'ParameterizedTypeReference mới >() {}' để tránh phân lớp con. – afaulconbridge

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