假设我在 Spring 服务层中有以下方法定义:
@Override
public boolean passwordsMatch(String encrypted, String plain) {
if (encrypted == null || encrypted.isEmpty() || plain == null || plain.isEmpty()) {
throw new IllegalArgumentException("One argument is null or empty");
}
return passwordEncoder.matches(plain, encrypted);
}
它由Spring MVC应用程序控制器调用,该控制器想要检查用户提供的新密码(此处称为"纯密码"(是否与用户的当前密码(此处称为"加密"(匹配。
如果用户提供的新密码为空(plain.isEmpty()
(,我真的应该抛出一个非法参数异常(或运行时异常的任何子类型(吗?
我 95% 确定我会删除这张支票,但我很想知道在这种特殊情况下支持保留支票的论点。
每当你在方法中得到一个你不喜欢的参数时,IllegalArgumentException
应该是你的首选(这就是这个例外的目的(。因此,除非您已经拥有(或觉得有必要实现(更具体/有意义的异常,否则为了保持一致性,我认为坚持使用IllegalArgument/IllegalState是可以的。
但是,最好在异常消息中指出您不喜欢的特定参数。顺便说一下,Guava通过其Preconditions
实用程序为此类验证提供了非常好的支持。
Preconditions.checkArgument(encrypted != null && !encrypted.isEmpty(), "The old password hash is empty");
Preconditions.checkArgument(plain != null && !plain.isEmpty(), "The new password is empty");
既然您已经澄清了实际的问题范围,我想说的是,在弄清楚该方法应该检查什么之后,您是唯一一个决定您的方法是否应该继续(如果提供 null 或空参数(的人。
根据您的方法名称,我会说它最多应该禁止null
值,因为空密码仍然可以与其加密表示形式匹配。"最小密码长度"规则很可能应该在其他地方实施;此方法应仅报告纯密码是否与哈希匹配,而不考虑它是否为合法密码。
我写得太快了。该方法似乎是用于比较密码的某种服务方法。域无关紧要。在这种特定情况下,例如,如果提供的参数null
,则抛出IllegalArgumentException
是有意义的,但对于空字符串则不然,因为这实际上可能是密码。
在涉及域验证的用例中,我不会使用 IllegalArgumentException
.如果User
实例的密码为空,则该实例(或其他实例(将不会处于有效状态。因此,您应该抛出某种InvalidDomainException
,例如。 InvalidPasswordException
(或使用带Validator
的BindingResult
(。