Java api 返回可选

Java api returning Optional

我正在与 API 通信,并且我已经使用了 Optional class。但我觉得错误处理可以更优雅,所以任何关于如何改进它的建议都会受到欢迎。另外,我是否在实际 api 调用中缺少异常处理?

public Optional<Account> getGreenqloudAccount(String accountUUid) {
    System.out.println("tmplog: GreenqloudAccountDao->getGreenqloudAccount");
    for (Account account : apiClient.accountList()) {
        if (account.getUuid().equals(accountUUid)) {
            System.out.println("getGreenqloudAccount, account: " + account.toString());
            return Optional.of(account);
        }
    }
    return Optional.empty();
}

public Optional<String> getMarketplaceCustomerIdByUsername(String username) {
    if (username == null || username.equals("")) {
        return Optional.empty();
    }
    AwsMarketplace marketplaceData = apiClient.getMarketplaceData(getKeys(username));
    if (marketplaceData == null) {
        return Optional.empty();
    }
    return Optional.ofNullable(marketplaceData.getObjects().get(0).getCustomerId());
}

private Pair getKeys(String username) {
    GetKeys getKeys = apiClient.getKeys(username);
    return new Pair(getKeys.getApiPrivateKey(), getKeys.getApiPublicKey());
}

您可以使用 Optional.isPresent()

进行支票

使用Optional.orElseThrow(Supplier<? extends X> exceptionSupplier)

阅读关于可选的 JDK8 文档 here

此外,您可能希望在检查空字符串之前trim输入参数

您的代码的主要问题:您将大量非常不同的结果放入相同的"bucket"。

getMarketplaceCustomerIdByUsername() 例如 returns 一个空的 Optional when:

  • 用户名为空
  • 用户名是“”(想想""是空的,但是" "不是空的?!)
  • 找不到给定用户的 AwsMarketplace 实例

如前所述,这些是非常不同的问题。第一个可能表明:提供的用户名错误,因此您应该将此告知您的用户。最后一个表示:"something is fishy, maybe the user is unknown, or something else happened".

因此:考虑不要将不同的结果缩减为一个空的 Optional。而是考虑抛出(不同的?)异常。当 "no result" 是 valid 操作结果时,您可以使用 Optional。但是 "no result, because bad user name" 感觉不是一个有效的结果。

如果你的意思是处理极端情况,你可以像第一种方法一样使用 findFirst 来提高代码的可读性,例如:

public Optional<Account> getGreenqloudAccount(String accountUUid) {
    System.out.println("tmplog: GreenqloudAccountDao->getGreenqloudAccount");
    return apiClient.accountList().stream()
            .filter(account -> account.getUuId().equals(accountUUid))
            // you can 'peek' and log 
            .findFirst(); // you return the first account or empty 
}

进一步了解其他 API,注意 Optional.map 处理返回 null 值的操作,并为它们隐式处理 returns Optional.empty。所以你可以使用:

public Optional<String> getMarketplaceCustomerIdByUsername(String username) {
    return Optional.ofNullable(username) // if username is null empty
            .filter(name -> !name.isEmpty()) // empty string returns filtered out
            .map(name -> apiClient.getMarketplaceData(getKeys(name))) // handles 'null' calue returned
            .map(marketplaceData -> marketplaceData.getObjects().get(0).getCustomerId()); // here as well
}