如何将泛型类作为方法的泛型参数传递

时间:2017-08-17 13:37:46

标签: java spring generic-collections

我有一个问题,即将类作为方法的通用参数传递,例如。我有一个简单的方法:

Route::prefix('productos')->group(function () {

    'as' => 'products.index', 
    'uses' => 'ProductController@index'

    Route::get('crear',[
        'as' => 'products.create', 
        'uses' => 'ProductController@create'
    ]);
    Route::post('guardar',[
        'as' => 'products.store', 
        'uses' => 'ProductController@store'
    ]);
    // Editar, borrar
    Route::get('{id}',[
        'as' => 'products.destroy', 
        'uses' => 'ProductController@destroy'
    ]);
    Route::get('{id}/editar',[
        'as' => 'products.edit', 
        'uses' => 'ProductController@edit'
    ]);
    Route::put('{id}',[
        'as' => 'products.update', 
        'uses' => 'ProductController@update'
    ]);
});

解析对指定表单的响应。我以这种方式使用它们:

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

对于ItemListJSON.class看起来像这样:

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

一切都很好。但我的问题是:

是否可以将泛型类作为 sendRequest 方法的参数传递?

我希望ItemListJSON类是通用的,在我的情况下:

@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 方法时:

@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...
}

我在Eclipse IDE上收到警告

  

类型安全:需要取消选中ItemListJSON类型的表达式   转换为符合ItemListJSON

当调用方法时,我在服务器控制台中出错:

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

@EDIT:

我重新编写了sendRequest方法,发现processResponse方法发生了错误,其中是ObjectMapper对对象的响应映射。

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

2 个答案:

答案 0 :(得分:1)

使用

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"));

请参阅从the rest template intro

剪下的代码
Transporter.EndpointAddr

答案 1 :(得分:1)

您可以通过传递com.fasterxml.jackson.core.type.TypeReference代替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());
    }
}