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
}
我正在与 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
}