到目前为止,我已经创建了一个包含webclient和一些方法的类
public class CustomWebClient<T> {
private final WebClient webClient;
public CustomWebClient(WebClient.Builder builder, ClientProperties properties) {
String rootUrl = properties.getHttp().getRootUrl();
webClient = builder
.baseUrl(rootUrl)
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.defaultHeaders(httpHeaders -> httpHeaders.setAll(properties.getHeaders()))
.build();
}
public Mono<ResponseEntity<T>> setRequest(final String uri,
final HttpMethod httpMethod,
final Class<T> classToMap) {
WebClient.RequestHeadersSpec<?> requestHeadersSpec = webClient.method(httpMethod).uri(uri);
WebClient.ResponseSpec responseSpec = setRetrievingOptions(requestHeadersSpec);
return setEntity(responseSpec, classToMap);
}
private WebClient.ResponseSpec setRetrievingOptions(final WebClient.RequestHeadersSpec<?> requestHeadersSpec) {
return requestHeadersSpec.retrieve()
.onStatus(HttpStatus::is4xxClientError,
clientResponse -> Mono.error(new ResponseStatusException(clientResponse.statusCode(), NOT_FOUND_MSG)))
.onStatus(HttpStatus::is5xxServerError,
clientResponse -> Mono.error(new ResponseStatusException(clientResponse.statusCode(), INTERNAL_SERVER_ERROR_MSG)));
}
private Mono<ResponseEntity<T>> setEntity(final WebClient.ResponseSpec responseSpec, Class<T> classToMap) {
return responseSpec.toEntity(classToMap);
}
} 然后将CustomWebClient注入到另一个类中,它是一个服务。
public class ABCServiceImpl implements ABCService {
private final CustomWebClient<? extends BaseResponse> customClient;
private Mono<PageResponse> invokeGetPageFromABC(final String storeId, final String site, final MultiValueMap<String, String> queryParams) {
Mono<ResponseEntity<PageResult>> responseEntityMono = customClient.setRequest(String.format(PAGE_ENDPOINT, site), HttpMethod.GET, queryParams, PageResult.class);
return responseEntityMono.map(content ->
new ContentResponse(content.getStatusCode(), customWebClient.SUCCESS_MSG, createContent(content.getBody())));
}
private ContentDTO createContent(ContentResult contentResult){
return Optional.ofNullable(contentResult)
.filter(c -> Objects.nonNull(c.getContent()))
.map(ContentResult::getContent)
.orElse(new ContentDTO());
}
}此时,获取编译时错误,该错误为
Required type: Class <capture of ? extends BaseResponse>
Provided: Class <ContentResult>这是我要传递的对象
public class ContentResult extends BaseResponse {
private ContentDTO content;
}因为我是新来的仿制药,所以我可能遗漏了一些东西,或者我没有完全理解。知道问题出在哪里了吗?
老实说,考虑到我实际上已经在注入customWebClient时指定了超类,所以我希望能够工作。
提前谢谢你!
发布于 2021-03-26 00:40:14
我仔细看过了,我想我明白你想做什么了。我建议不要使用通配符("?")用这种方式。调用customClient.setRequest(..)时,编译器无法确定您有哪个版本的customClient (即BaseResponse的哪个子类),因此当您试图传递参数化的Class对象(它看起来是PageResult.class)时,它会抛出一个错误
您可以通过将ABCServiceImpl转换为参数化类(即具有字段属性为private final CustomWebClient<T extends BaseResponse> customClient的ABCServiceImpl<T extends BaseResponse> )来修复此问题;
但我也不会这么做,因为看起来您的自定义客户端根本不需要参数化类型!
所以我建议这样做:
public class CustomWebClient而不是public class CustomWebClient)public <T> Mono<ResponseEntity<T>> setRequest(..)使
public Mono<ResponseEntity<T>> setRequest(..)方法成为参数化方法:customWebClient.<ContentResult>setRequest(ContentResult.class, ...etc);
https://stackoverflow.com/questions/66807844
复制相似问题