2011-12-14 23 views
5

Używam usługi Spring's RestTemplate do nawiązywania połączeń z usługą sieciową REST. Jednym z tych wywołań jest zwrócenie listy obiektów określonego typu. Metody RestTemplate wymagają podania argumentu klasy w celu wskazania oczekiwanego typu zwrotu.Jak uniknąć ostrzeżeń kompilatora, gdy ogólne informacje o typie są niedostępne?

// restTemplate is type org.springframework.web.client.RestTemplate 
URI restServiceURI = new URI("http://example.com/foo") 
restTemplate.getForObject(restServiceURI, List<Foo>.class); 

Oczywiście to się nie kompiluje. Nie można uzyskać statycznej właściwości .class, gdy podajesz taki argument typu. Kod kompiluje się po usunięciu argumentu typu, ale generuje ostrzeżenie kompilatora rawtypes.

Moje pytanie jest proste. Czy utknąłem z tłumieniem ostrzeżenia kompilatora lub czy istnieje lepszy sposób kodowania tego?

Odpowiedz

3

Ale jak miałby RestTemplate wiedzieć przekonwertować elementy listy na instancje klasy Foo? Czy próbowałeś uruchomić kod i czy działa on zgodnie z oczekiwaniami?

Jednym ze sposobów, w jaki można to obejść, byłoby użycie tablicy jako typu danych wejściowych. na przykład.

restTemplate.getForObject(restServiceURI, Foo[].class); 

Ale nie wiem, czy to jest obsługiwane. Jeśli naprawdę potrzebujesz deserializacji bardziej złożonych typów danych, powinieneś rozważyć użycie Jackson lub Gson.

Z Jacksonem możesz użyć klasy ObjectMapper, aby łatwo deserializować dane z większości źródeł.

String input = ...; 
ObjectMapper mapper = new ObjectMapper(); 
List<Foo> list = mapper.readValue(input, new TypeReference<List<Foo>>(){}); 

Powyższe prace bo celowo utworzyć anonimową klasę, która rozciąga TypeReference klasa będzie pamiętał swoje typy rodzajowe w czasie wykonywania, a więc może pomóc mapowania obiektów do tworzenia list Foo. For a fuller explanation.

+0

Jackson jest na ścieżce klas, a Spring 3.x używa go automatycznie do wysyłania/rozpakowywania tych strumieni. Miałem nadzieję, że wykorzystam to na swoją korzyść, ale wydaje się, że muszę to zrobić na niższym poziomie. Jestem zaskoczony, że Spring nie zapewnia łatwego sposobu obsługi zwrotów Collection, podobnie jak w przypadku innych klas szablonów. –

+0

Ta metoda działa z udoskonaleniem. Zamiast używać RestTemplate.getForObject() używam RestTemplate.execute() i dostarczam własny ResponseExtractor. To prowadzi mnie przez dowód koncepcji, ale wyobrażam sobie, że istnieje bardziej sprytny sposób określenia typu odpowiedzi z serwera. W tej chwili zakładam JSON, ale w pewnym momencie będę musiał obsługiwać XML. Dzięki za wskazówki! –

0

Można to osiągnąć za pomocą tego:

List<Class<Foo>> classList = new ArrayList<Class<Foo>>(); 
restTemplate.getForObject(restServiceURI, classList); 

Jeśli jest tylko jeden przedmiot, a nie lista klasie wtedy można po prostu przejść jak poniżej:

restTemplate.getForObject(restServiceURI, Foo.class); 
+0

Twoja sugerowana metoda daje błędy kompilacji. –