2017-08-17 191 views
0

將泛型類作爲方法的泛型參數f.e.有問題。我有一個簡單的方法:如何將泛型類作爲方法的通用參數傳遞

<T> T sendRequest(SomeRestApiRequest request, Class<T> responseClass) 

哪些分析對指定表單的響應。我使用它們以這種方式:

ItemListJSON itemList = new ItemListJSON(); 
itemList = someRestClient.sendRequest(req, ItemListJSON.class); 

爲ItemListJSON.class它看起來像:

@JsonInclude(JsonInclude.Include.NON_NULL) 
@JsonPropertyOrder({"totalSize","items"}) 
public class ItemListJSON { 

    @JsonProperty("items") 
    private List<SalonJSON> items; 

    @JsonProperty("totalSize") 
    private int totalSize; 

    //...getters, setters... 
} 

,一切都很好。但我的問題是:

是否有可能通過泛型類作爲參數sendRequest方法?

我想這ItemListJSON類是通用的,在我的情況:

@JsonInclude(JsonInclude.Include.NON_NULL) 
@JsonPropertyOrder({"totalSize","items"}) 
public class ItemListJSON<T> { 

    @JsonProperty("items") 
    private List<T> items; 

    @JsonProperty("totalSize") 
    private int totalSize; 

    //...getters, setters... 
} 

但是當我試圖用這種方式sendRequest將方法:

ItemListJSON<SalonJSON> itemList = new ItemListJSON<SalonJSON>(); 
itemList = someRestClient.sendRequest(req, ItemListJSON.class); 

我得到了Eclipse的警告IDE

類型安全性:類型It emListJSON選中需要轉換 符合ItemListJSON

,當方法被稱爲我有在服務器控制檯錯誤:

SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to xxx.ServiceCategoryJSON] with root cause 
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to xxx.ServiceCategoryJSON 

@EDIT:

我debbuged我sendRequest將方法和我發現在processResponse方法中發生錯誤,其中通過ObjectMapper映射對對象的響應。

private <T> T processResponse(Response response, Class<T> responseClass) throws ParseException, IOException { 
     ObjectMapper om = new ObjectMapper(); 
     om.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);  
     return om.readValue(response.getBody(), responseClass); //throw exception 
    } 
+0

顯示'ŤsendRequest將主體(SomeRestApiRequest請求,類 responseClass)' – isah

+0

@isah我修改後以示出異常被拋出。 –

+0

什麼是JSON響應作爲字符串,'response.getBody()'(字符串化)? – isah

回答

1

剪斷的代碼,你可以做到這一點的方式Class<T>

public class GenericSerializationTest { 

@Data //lombok 
public static class ItemListJSON<T> { 
    private List<T> items; 
} 

@Data //lombok 
public static class StructureExample { 
    private final String name; 
    private final Double price; 
} 

public static class Sender { 
    private final ObjectMapper objectMapper = new ObjectMapper(); 

    public <T> T sendRequest(String json, TypeReference typeReference) throws IOException { 
     //sender logic - in this case I assume that json is API response 
     return objectMapper.readValue(json, typeReference); 
    } 
} 

@Test 
public void testMethod() throws IOException { 
    Sender sender = new Sender(); 
    ItemListJSON<StructureExample> test = sender.sendRequest("{\"items\": [{\"name\":\"MacBook Pro\",\"price\":101.345}, {\"name\":\"MacMini\",\"price\":102.345}]}", new TypeReference<ItemListJSON<StructureExample>>() {}); 

    assertEquals("Should contain only 2 items", 2, test.getItems().size()); 
    assertEquals("Name of first item is not correct", "MacBook Pro", test.getItems().get(0).getName()); 
    assertEquals("Name of second item is not correct", "MacMini", test.getItems().get(1).getName()); 
} 

}

+0

謝謝!這是一個很好的解決方案!你拯救我的一天! :) –

1

使用

ParameterizedTypeReference<ItemListJSON<SalonJSON>> typeRef = new ParameterizedTypeReference<ItemListJSON<SalonJSON>>() {}; 

通過傳遞com.fasterxml.jackson.core.type.TypeReference而不是見從the rest template intro

RestTemplate restTemplate = new RestTemplate(); 
ParameterizedTypeReference<List<String>> listOfString = new ParameterizedTypeReference<List<String>>() {}; 
ResponseEntity<List<String>> response= restTemplate.exchange(baseUrl,HttpMethod.GET,null, listOfString); 
HttpHeaders headers = response.getHeaders(); 
MediaType contentType = headers.getContentType(); 
long date = headers.getDate(); 
List<String> getOrDefault = headers.getOrDefault("X-Forwarded", Collections.singletonList("Does not exists")); 
相關問題