【问题标题】:A question about exception catching in Java关于Java中异常捕获的问题
【发布时间】:2011-05-31 16:25:16
【问题描述】:

我有一个实例方法,在里面我做了一个简单的网页解析:

public void doOperation(final AuthorAccess authorAccess, ArgumentsMap arguments) throws  IllegalArgumentException,AuthorOperationException
{

    final String server = "chiexist1.worldbook.com";
    final String port = "8080";
    try {

             docBuilder = docFactory.newDocumentBuilder();
             doc = docBuilder.parse("http://" + server + ":" + port + "/exist/webdav/db/portfolio/config/products.xml");
        ...}
       catch{}
  }

因为目前我在字符串中硬编码服务器地址,可能会出现服务器名称不正确的情况,所以在这种情况下,我希望它自动将服务器 URL 字符串更改为“localhost”。

我认为 if-else 语句可能会起作用,但我不太确定如何确定用于检测此解析是否失败的布尔变量。我也想把这个放在catch语句中,但是其他语句也抛出异常呢?

我还检查了 DocumentBuilder 的 API,parse() 方法总是返回一个文档类型而不是布尔值。所以如果有人能在这里给我一些关于如何检测错误的 URL 然后改为解析 localhost 的建议,我将不胜感激,在此先感谢。

【问题讨论】:

  • 我猜如果 URL 无效,它会返回一个 IOException,但可能还有许多其他原因会引发一个 IOException。顺便问一下,您说的“服务器名称不对”,您的意思能更准确吗?
  • @Gregs 这基本上意味着我正在访问一些我无权访问的其他公司服务器,所以我被屏蔽了。但是,本地主机将始终有效。
  • 感谢您的信息。顺便说一句,我看到我写的是“返回一个 IOException”而不是“抛出一个 IOException”。我很快就会去鞭刑室报告。
  • @Gregs:我之前认为应该是 IOException,但实际上在我的代码中,只有 SAXException 才能正确捕获异常。

标签: java


【解决方案1】:

我想在这里你可以找到答案:Validating URL in Java

【讨论】:

【解决方案2】:

一般提示:不要只写“catch”。始终指定您要捕获的异常类型(最好是您自己的自定义异常类型),以便您知道代码完全按照您的意思执行。否则,正如您所说,catch 语句可能会捕获一些其他类型的异常,这些异常您并不打算发生,实际上应该向上抛出。

【讨论】:

    【解决方案3】:

    下面的代码应该做你喜欢的事情。基本上,在catch 中只需从 localhost 构建另一个文档。

    final String server = "chiexist1.worldbook.com";
    final String port = "8080";
    docBuilder = docFactory.newDocumentBuilder();
    doc = null;
    try {
        doc = docBuilder.parse("http://" + server + ":" + port + "/exist/webdav/db/portfolio/config/products.xml");
    } catch{
        try{ 
            doc = docBuilder.parse("http://" + "localhost" + ":" + port + "/exist/webdav/db/portfolio/config/products.xml");
        } catch {
            // now we have an error we can't recover from
        }
    }
    ...  // I meant to do this before.
    

    【讨论】:

    • 在 try 中仅包装 "doc = docBuilder.parse(...)" 语句可能是一个更好的主意。这样它就避免了从进一步的语句中捕获异常。如果能把异常的类型缩小,那就更好了。
    • @Marti,是的,那是我的错。我忘了移动...
    • @marc,哎呀,是的。我不是故意的。
    • @jjnguy,问题是,我需要保留最外层的 try 块。我可以嵌套它们吗?
    【解决方案4】:

    跟踪变量中的尝试次数并循环,直到通过成功或最大尝试次数(我选择了 5):

    String server = "chiexist1.worldbook.com";
    final String port = "8080";
    int attempts = 0;
    final int MAX_ATTEMPTS = 5;
    boolean success = false;
    docBuilder = docFactory.newDocumentBuilder();
    while (!success && attempts < MAX_ATTEMPTS) {
        try {
            doc = docBuilder.parse("http://" + server + ":" + port + "/exist/webdav/db/portfolio/config/products.xml");
            success = true;
        } catch (IOException e) {
            if (++attempts < MAX_ATTEMPTS) {
                System.err.println("Attempt to connect to " + server + ":" + port + " failed. Retrying" + (attempts == 1 ? ", but connecting to localhost:" + port + " this time" : "") + ".");
                server = "localhost";
            } else {
                System.err.println("Attempt to connect to " + server + ":" + port + " failed. Giving up after " + attempts + " failed attempts.");
            }
        } 
    }
    if (!success) {
        // Tidy up and exit
    }
    // Do stuff
    

    【讨论】:

      【解决方案5】:

      您应该分别捕获相应的异常,并根据您捕获的异常执行不同的错误处理逻辑。这被认为是最好的方法,因为它将错误条件与正常逻辑分开,并且您可以对不同的错误进行不同的处理。

      它被认为比正常逻辑流程中的 if else 语句更好。

      【讨论】:

        【解决方案6】:

        试试这样的:

        static String hostname = "hostname";
        static{
           if(doesHostExist(hostName)==false){
             hostname="localhost";
           }
        }
        
        private static boolean doesHostExist(String host){
          try {
            URL url = new URL("http://" + host);
            URLConnection conn = url.openConnection();
            conn.connect();
            return true;
          } catch (MalformedURLException e) {
            return false;
          } catch (IOException e) {
            return false;
          }
        
        }
        

        *编辑从上一个答案中提取的附加代码:Validating URL in Java

        【讨论】:

          猜你喜欢
          • 2011-03-16
          • 2013-03-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-28
          • 2012-12-22
          • 2012-12-07
          • 1970-01-01
          相关资源
          最近更新 更多