在方法内部,需要一个条件来进行逻辑处理。我的IDE中显示未处理的异常警告消息。用try-catch包裹整个块不会使消息消失。
public void changePassword(String login, String currentClearTextPassword, String newPassword) {
userRepository.findOneByLogin(login)
.ifPresent(user -> {
String currentEncryptedPassword = user.getUserSecret();
String encryptedInputPassword = "";
try {
encryptedInputPassword = authUtils.encrypt(currentClearTextPassword);
} catch (Exception ex) {
System.err.println("Encryption exception: " + ex.getMessage());
}
if (!Objects.equals(encryptedInputPassword, currentEncryptedPassword)) {
throw new Exception("Invalid Password"); // <-- unhandled exception
}
String encryptedNewPassword = "";
try {
encryptedNewPassword = authUtils.encrypt(newPassword);
} catch (Exception ex) {
System.err.println("Encryption exception: " + ex.getMessage());
}
user.setUserSecret(encryptedNewPassword);
userRepository.save(user);
log.debug("Changed password for User: {}", user);
});
}
如何处理此警告消息?
答案 0 :(得分:3)
在流操作内部处理异常会产生一些开销,我想将操作分开并使其:
public void changePassword(String login, String currentClearTextPassword, String newPassword) throws Exception {
//get the user in Optional
Optional<User> check = userRepository.findOneByLogin(login);
//if the user is present 'isPresent()'
if(check.isPresent()){
//get the user from the Optional and do your actions
User user = check.get();
String currentEncryptedPassword = user.getUserSecret();
String encryptedInputPassword = "";
try {
encryptedInputPassword = authUtils.encrypt(currentClearTextPassword);
} catch (Exception ex) {
throw new Exception("Encryption exception: " + ex.getMessage());
}
if (!Objects.equals(encryptedInputPassword, currentEncryptedPassword)) {
throw new Exception("Invalid Password"); // <-- unhandled exception
}
String encryptedNewPassword = "";
try {
encryptedNewPassword = authUtils.encrypt(newPassword);
} catch (Exception ex) {
throw new Exception("Encryption exception: " + ex.getMessage());
}
user.setUserSecret(encryptedNewPassword);
userRepository.save(user);
log.debug("Changed password for User: {}", user);
}
}
除了抛出异常外,还应该抛出异常。
答案 1 :(得分:0)
就像@ louis-wasserman一样,您可以使用未经检查的异常。
所以不是
throw new Exception("Invalid Password");
使用:
throw new RuntimeException("Invalid Password"); // for example
注意:最好使用适合您的用例的自定义RuntimeException。
答案 2 :(得分:0)
对于一般情况,@ pari-ngang是正确的:在lambda表达式中,您无法在调用函数之外处理已检查的异常。在lambda中使用未经检查的结构或使用try
构造。
但是,需要执行这两项操作可能表明结构不良。一个这样的征兆就是在lambda中包含大量代码。以下是针对您的具体情况的一些建议:
1 。为了简化@ ycf-l的答案,请反转逻辑,如果找不到则返回user
:
Optional<User> user = userRepository.findOneByLogin(login);
if (!user.isPresent()) {
return;
}
// ... carry on as before outside of a lambda
2 。将获取用户与更改用户密码的逻辑分开(您仍然必须传递异常备份):
if (user.isPresent()) {
changePassword(user.get(), currentClearTextPassword, newPassword);
}
3 。您还可以使用vavr之类的库来简化try
/ catch
块:
String encryptedInputPassword = Try.of(() -> authUtils.encrypt(currentClearTextPassword))
.onFailure(e -> System.err.println("Encryption exception: " + e.getMessage()))
.orElse("");
4 。如果您愿意使用vavr,也可以解决更普遍的问题:
userRepository.findOneByLogin(login)
.map(user -> Try.of(() -> {
// Your change password stuff goes here.
changePassword(user, currentClearTextPassword, newPassword);
return null; // I don't currently know of any way of passing a runnable.
}))
// This pulls the exception out of the lambda function, satisfying the compiler.
.orElseGet(() -> Try.success(null))
.getOrElseThrow(Function.identity());
我还没有使用过vavr,因此无法告诉您这是否是最有效/最干净的vavr方法/用法,但是它将解决您的问题。