我已经在这里待了几个小时,但似乎无法解开它。错误与这段代码有关:
(此问题底部的完整代码。我正在使用屏幕截图直观地显示问题。)
错误本身是:
不存在类型变量U的实例,因此GetUsersForAdAccountResponse符合CompletionStage
在thenCompose
链的最开始,我擦除了return
,并使用IntelliJ的“引入局部变量...” 功能来查看整个链(直到第1118行,包括第1118行)正在返回:
结果是
final CompletionStage<U> uCompletionStage = ...
但是您可以看到包围方法的返回类型为
public CompletionStage<GetUsersForAdAccountResponse> ...
是什么导致编译器无法推断GetUsersForAdAccountResponse
? (再次,通常这里是return
。)
在此过程中,我还尝试在每个thenCompose
处引入局部变量,它们似乎都是正确的。每个产生一个CompletionStage<Foo>
,下一个thenCompose
提供一个期望Foo
的lambda并产生CompletionStage<Bar>
,依此类推。 (在一次代码重组中,我确实看到了一个嵌套的CompletionStage<CompletionStage<Foo>>
,但我认为那是我自己重写的产物。)
我不知道是否有帮助,但这是整个方法:
@Override
public CompletionStage<GetUsersForAdAccountResponse> getUsersForAdAccount(
RequestContext context, GetUsersForAdAccountRequest request) {
Uuid adAccountId = request.getAdAccountId();
return verifyAuthorization(context,
PortcullisTemplates.Action.GET_USERS_FOR_AD_ACCOUNT.getName(),
portcullisTemplates.topOrganizationResource())
.thenCompose(auditLogPrincipal -> jdbiExecutor.executeInTransaction(handler -> {
// We purposely safeguard the account lookup as well behind Portcullis.
AdAccountDao adAccountDao = handler.attach(AdAccountDao.class);
if (adAccountDao.getAdAccountById(adAccountId) == null) {
throw new ValidationException(SERVICE_NAME,
"Ad account not found: " + UuidUtils.toString(adAccountId));
}
AdAccountRoleUserMappingDao roleDao = handler.attach(AdAccountRoleUserMappingDao.class);
List<String> roleNames = request.getRoleNamesList();
return roleNames.isEmpty() ?
roleDao.getAdAccountRoleUserMappingsByAdAccount(adAccountId) :
roleDao.getAdAccountRoleUserMappingsByAdAccountAndRoles(adAccountId, roleNames);
})).thenCompose(adAccountRoleUserMappings -> jdbiExecutor.execute(UserDao.class, userDao -> {
return userDao
.getUsersBy]UserIds(
adAccountRoleUserMappings.stream()
.map(AdAccountRoleUserMapping::userId)
.collect(Collectors.toList())
).stream()
.collect(Collectors.toMap(
User::userId,
user -> new EncryptedFieldsBuilder()
.firstName(user.encryptedFirstName())
.lastName(user.encryptedLastName())
.email(user.encryptedEmail())
.build()
));
}).thenCompose(
userEncryptedFields -> padlockService.decryptUserAccounts(userEncryptedFields)
).thenCompose(decryptedUsers -> GetUsersForAdAccountResponse.newBuilder()
.addAllUserWithRole(
adAccountRoleUserMappings.stream()
.filter(mapping -> decryptedUsers.containsKey(mapping.userId()))
.map(mapping -> UserWithRole.newBuilder()
.setAccount(decryptedUsers.get(mapping.userId()))
.setRoleName(mapping.roleName())
.build())
.collect(Collectors.toSet())
).build()
));
}
答案 0 :(得分:4)
链中的最后一个thenCompose
应该是thenApply
。传递给它的函数返回一个GetUsersForAdAccountResponse
而不是CompletionStage
。
thenCompose
是flatMap
中的CompletableFuture
。它需要一个返回CompletionStage
并展平结果的函数。