Java 当用户会话过期或返回null时引发异常

Java 当用户会话过期或返回null时引发异常,java,session,exception,exception-handling,java-8,Java,Session,Exception,Exception Handling,Java 8,这个问题更多的是关于设计和干净的代码,我很难理解什么时候应该抛出一个选中的期望值,或者什么时候我们应该返回一个null值,并检查客户机上的这个值是否为null 据我所知,在异常情况可能发生但我们无法阻止的情况下,应使用检查异常。我还读到,我们不应该使用异常作为控制流 所以在我的例子中,我正在编写一个并发应用程序,其中有很多用户会发出请求,我有一个方法可以检查用户会话是否过期(10分钟后过期),因此,我应该抛出一个异常,因为我无法阻止这种情况,但另一方面,如果这种情况每10分钟发生一次,那么异常代

这个问题更多的是关于设计和干净的代码,我很难理解什么时候应该抛出一个选中的期望值,或者什么时候我们应该返回一个null值,并检查客户机上的这个值是否为null

据我所知,在异常情况可能发生但我们无法阻止的情况下,应使用检查异常。我还读到,我们不应该使用异常作为控制流

所以在我的例子中,我正在编写一个并发应用程序,其中有很多用户会发出请求,我有一个方法可以检查用户会话是否过期(10分钟后过期),因此,我应该抛出一个异常,因为我无法阻止这种情况,但另一方面,如果这种情况每10分钟发生一次,那么异常代价会很高,如果我返回null并检查客户端,可能会提高性能。在这种情况下你会怎么做

这是我的方法:

@Override
public Integer getUserIdBySessionKey(String sessionKey) {
    User user = userSessions.get(sessionKey);
    boolean isUserSessionValid = isUserSessionValid(user);
    return isUserSessionValid ? user.getUserId() : null;
}

当您希望向调用代码发出必须考虑的重要异常情况的信号,并且可以对其采取有意义的操作时,应该使用选中的异常。例如,在对用户进行身份验证时,密码可能错误或帐户已过期,因此选中的AuthenticationException或AccountExpiredException可能是合理的。客户机代码将捕获这些异常并适当地处理它们

另一方面,如果没有合理的行动可以采取,或者是足够通用的,可以用通用的方式处理的情况,则应该是未经检查的例外情况。任何编码错误(NullPointerException、IllegalStateException、数据库错误、网络错误等)都属于这一类

所以问题是,您希望调用代码对会话过期做些什么吗?如果您有一个通用机制来处理这种情况(例如顶级ServletFilter或类似的机制),它捕获此类异常并重定向到登录页面,那么将其设置为未检查的异常。如果这需要调用代码特别注意,请检查它


在您的情况下,我会将其取消选中,并在顶层以通用方式进行处理。

我有一种方法,可以检查用户会话是否过期:如果会话过期,我将返回true,否则返回false。我猜你的方法实际上并没有做到这一点。发布代码而不是描述它。@JB Nizet,完成。我的问题是,到目前为止,我返回null是因为会话无效,但我可能会抛出一个“ExpiredSessionException”,在一个选项或另一个选项之间选择可能不是什么大问题,但我希望以尽可能干净的方式执行。如果调用代码有机会从这种情况中恢复,那么我将返回一个可选的。另一方面,如果调用代码不应该处理这种情况,并且您只希望在会话无效时调用全局异常处理程序,那么我将抛出一个运行时异常。在任何情况下,我都不会抛出选中的异常。好的,这很有用,谢谢!好的,从客户端我只需要知道哪种类型的异常是,返回给客户端适当的http错误(在本例中为400 unhorized)。如果使用运行时异常执行此操作,则无法区分不同的异常。因此,在这种情况下,检查过的表达式可能更合适,但如果我不发送表达式,而是返回一个可选的表达式,并且如果(可选的.isPresent)返回Http.Unhorized,则我在客户端执行检查,那么我仍然可以区分它,对吗?您可以创建扩展RuntimeException的SessionExpiredException。这将使它成为一个未检查的异常,您可以在顶层捕获并适当处理(返回400)。不需要创建检查过的异常。顺便说一下,返回null或状态代码不是Java处理异常情况的方法。它适用于C(或其他没有异常处理机制的语言),但不适用于Java。