将 class 的 T 泛型类型获取到新的 GenericType<List<T>>() Java 中的 T
Get T generic type of the class to the T in the new GenericType<List<T>>() Java
我已经实施了以下 class 并使用 REST 调用为给定类型的 T 实施了搜索方法获取对象列表。
public class AmapiService<T extends Resource> implements RestService<T> {
@Override
public List<T> search( MultivaluedMap<String, String> aQueryParams ) {
MultivaluedMap<String, String> lQueryParams = aQueryParams;
Client lClient = buildClient();
WebTarget ltarget = lClient.target( iRestDriver.target( aApiUrl ).getUri() );
for ( String lKey : lQueryParams.keySet() ) {
ltarget = ltarget.queryParam( lKey, lQueryParams.getFirst( lKey ) );
}
List<T> lObjects = null;
lObjects = ltarget.request( MediaType.APPLICATION_JSON ).get( new GenericType<List<T>>() {
} );
return lObjects;
}
}
这是为 class 和搜索方法调用创建实例的方式。
AmapiService<RFQDefinition> RFQService =
new AmapiService<RFQDefinition>();
List<RFQDefinition> qfq = RFQService.search( lQueryParam );
当我 运行 我收到以下错误时
May 07, 2018 1:48:14 PM org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor aroundReadFrom
SEVERE: MessageBodyReader not found for media type=application/json, type=interface java.util.List, genericType=java.util.List<T>.
这意味着 RFQDefinition 没有设置为 new GenericType<List<T>>().
中的 T
如何将 AmapiService<T extends Resource>
中的 T 类型设置为 new GenericType<List<T>>()
如果我定义它new GenericType<List<RFQDefinition>>()
而不是 T 它的工作
与通用无关。
服务器抱怨它没有任何 MessageBodyReader
来读取 application/json
正文。
通常,您可以将 Jackson
添加为 json decode/encode 用于您的申请
读这个:
https://jersey.github.io/documentation/latest/media.html#json.jackson
您对泛型的使用实际上在这里没有用处。
没有真正的通用实现,因为您的响应基于您提供给您使用的服务的参数 (.get( new GenericType<List<T>>(){})
)。类型参数对此没有帮助,因为代码是由 jax-rs 实现调用的,它不通过静态链接。
换句话说,没有代码会被编译,并且 运行 使用参数 class/method 来对抗你的 class/method:
//this is not a valid use-case:
List<ActualType> res = search(aQueryParams);
对此的简单翻译可以是:Java 泛型不会进入 REST API。您必须为您的 API 应该 return 的模型静态使用 Java 类型(就像您对 new GenericType<List<RFQDefinition>>()
所做的那样)。
我已经像这样更改了搜索方法实现,现在它可以工作了。
iClass 你可以把这个作为参数 eg: RFQDefinition.class
ObjectMapper mapper = new ObjectMapper();
JavaType type = mapper.getTypeFactory().constructCollectionType( List.class, iClass );
List<T> lObjects = null;
JsonArray lResponse = ltarget.request( MediaType.APPLICATION_JSON ).get( JsonArray.class );
try {
lObjects = mapper.readValue( lResponse.toString(), type );
} catch ( JsonParseException e ) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch ( JsonMappingException e ) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch ( IOException e ) {
// TODO Auto-generated catch block
e.printStackTrace();
}
我已经实施了以下 class 并使用 REST 调用为给定类型的 T 实施了搜索方法获取对象列表。
public class AmapiService<T extends Resource> implements RestService<T> {
@Override
public List<T> search( MultivaluedMap<String, String> aQueryParams ) {
MultivaluedMap<String, String> lQueryParams = aQueryParams;
Client lClient = buildClient();
WebTarget ltarget = lClient.target( iRestDriver.target( aApiUrl ).getUri() );
for ( String lKey : lQueryParams.keySet() ) {
ltarget = ltarget.queryParam( lKey, lQueryParams.getFirst( lKey ) );
}
List<T> lObjects = null;
lObjects = ltarget.request( MediaType.APPLICATION_JSON ).get( new GenericType<List<T>>() {
} );
return lObjects;
}
}
这是为 class 和搜索方法调用创建实例的方式。
AmapiService<RFQDefinition> RFQService =
new AmapiService<RFQDefinition>();
List<RFQDefinition> qfq = RFQService.search( lQueryParam );
当我 运行 我收到以下错误时
May 07, 2018 1:48:14 PM org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor aroundReadFrom
SEVERE: MessageBodyReader not found for media type=application/json, type=interface java.util.List, genericType=java.util.List<T>.
这意味着 RFQDefinition 没有设置为 new GenericType<List<T>>().
如何将 AmapiService<T extends Resource>
中的 T 类型设置为 new GenericType<List<T>>()
如果我定义它new GenericType<List<RFQDefinition>>()
而不是 T 它的工作
与通用无关。
服务器抱怨它没有任何 MessageBodyReader
来读取 application/json
正文。
通常,您可以将 Jackson
添加为 json decode/encode 用于您的申请
读这个:
https://jersey.github.io/documentation/latest/media.html#json.jackson
您对泛型的使用实际上在这里没有用处。
没有真正的通用实现,因为您的响应基于您提供给您使用的服务的参数 (.get( new GenericType<List<T>>(){})
)。类型参数对此没有帮助,因为代码是由 jax-rs 实现调用的,它不通过静态链接。
换句话说,没有代码会被编译,并且 运行 使用参数 class/method 来对抗你的 class/method:
//this is not a valid use-case:
List<ActualType> res = search(aQueryParams);
对此的简单翻译可以是:Java 泛型不会进入 REST API。您必须为您的 API 应该 return 的模型静态使用 Java 类型(就像您对 new GenericType<List<RFQDefinition>>()
所做的那样)。
我已经像这样更改了搜索方法实现,现在它可以工作了。 iClass 你可以把这个作为参数 eg: RFQDefinition.class
ObjectMapper mapper = new ObjectMapper();
JavaType type = mapper.getTypeFactory().constructCollectionType( List.class, iClass );
List<T> lObjects = null;
JsonArray lResponse = ltarget.request( MediaType.APPLICATION_JSON ).get( JsonArray.class );
try {
lObjects = mapper.readValue( lResponse.toString(), type );
} catch ( JsonParseException e ) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch ( JsonMappingException e ) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch ( IOException e ) {
// TODO Auto-generated catch block
e.printStackTrace();
}