如何在读取时出现IOException时返回500状态码

5

假设我有以下代码片段:

public boolean checkListing() {

    try {

        // open the users.txt file
        BufferedReader br = new BufferedReader(new FileReader("users.txt"));

        String line = null;
        while ((line = br.readLine()) != null) {
            String[] values = line.split(" ");
            // only interested for duplicate usernames
            if (username.equals(values[0])) {
                return true;
            }
        }
        br.close();
        return false;
    } catch (IOException e) {
        e.printStackTrace();
        // what to do here
    }

}

如果发生异常,我应该如何处理错误?我想知道它发生了,并将一个500代码返回给用户。

我是否应该抛出异常并在其他类中捕获它?

是否有更优雅的方法来获取反馈?


1
  1. 抛出异常并将初始异常作为原因;2) 使用组合 {result, code, failure reason} 对象进行返回。我更喜欢使用第一种方法,因为它既优雅又实用:在任何执行点上,您都可以获得完整的失败跟踪。
- Alex Salauyou
@SashaSalauyou 谢谢你的回答。不过我有点难以理解。你能给我一个阅读更多关于第二种方法的来源吗? - Rentonie
顺便提一下,在finally块中不要忘记关闭br,否则失败的序列可能会导致资源泄漏。 - Alex Salauyou
@SashaSalauyou 对不起,但是正如我所说,我没有理解你的建议。如果我不能完全理解,请原谅。 - Rentonie
我的意思是所有资源,如FileReaderBufferedReader都应该在执行结束时关闭。在我的答案中,我提供了代码片段来自动管理它。 - Alex Salauyou
不了解这段代码的上下文,无法回答。 - Raedwald
4个回答

1

你可以返回这个类的实例:

public class Result {

    private boolean errorOccurs;
    private boolean isValid;
    private Exception exception;

    public Result(boolean isValid){
        this(isValid, false, null);
    }

    public Result(boolean isValid, boolean errorOccurs, Exception exception){
        this.isValid = isValid;
        this.errorOccurs = errorOccurs;
        this.exception = exception;
    }

    public boolean isValid(){
        return isValid;
    }

    public boolean errorOccurs(){
        return errorOccurs;
    }

    public Exception getException(){
        return exception;
    }
}

在你的情况下:
public Result checkListing() {

    try {

        // open the users.txt file
        BufferedReader br = new BufferedReader(new FileReader("users.txt"));

        String line = null;
        while ((line = br.readLine()) != null) {
            String[] values = line.split(" ");
            // only interested for duplicate usernames
            if (username.equals(values[0])) {
                return new Result(true);
            }
        }
        br.close();
        return new Result(false);
    } catch (IOException e) {
        e.printStackTrace();
        return new Result(false, true, e);
    }
}

还有Result类的简短形式:)

public class Result {
    public boolean errorOccurs;
    public boolean isValid;
    public Exception exception;
}

正是我所需要的。非常感谢您准确的回答,先生。 - Rentonie

0
更好的方法是抛出包装异常:
try (FileReader fr = new FileReader("users.txt")) {
    try (BufferedReader br = new BufferedReader(fr)) {

        // ... do your work

    } catch (IOException e) {
        throw new RuntimeException(e);
    }
} catch (IOException e1) {
    throw new RuntimeException(e1); 
}

请注意,这里我在try语句中打开资源,因此使它们在执行结束时自动关闭,而不依赖于执行结果。

0
在这种情况下,readLineclose可能会抛出IOException异常。
此异常表示发生了异常情况,例如流的源不再可用。您的程序可以通过重新读取源或向用户报告此问题来恢复,具体取决于您的逻辑,这里没有首选的方法。
请注意,您应该在finally块中关闭br

0

我看到的最常见的两种方法是,正如Sasha Salauyou所指出的,重新抛出(可能被包装)或提供更多信息的单独对象。

你试图解决的根本问题是,你有一个想要返回超过两个值的方法,但返回类型只能表达两个值。因此,你必须返回支持你需要的所有可能返回值的类型,或者你必须找到替代的返回路径(如异常)。

在我的代码中,我倾向于在这里使用重新抛出。编写专用的返回对象在长期维护IO方面变得困难,因为有很多不同的方式可以失败。然而,我会偏离建议的路线(将原始异常作为原因的异常),因为通常没有包装的强烈理由。只需声明checkListing方法抛出IOException,在catch块中记录你的消息或堆栈跟踪,然后抛出原始异常即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接