创建Java异常子类以呈现自定义消息

问题描述

我有一个安全软件包,其中的类文件共享公用的Exception

    catch (InvalidKeyException | NoSuchAlgorithmException e) {
            System.err.println("Key Exception: Invalid key is detected to sign or verify signature." + " \n");
        } catch (UnrecoverableKeyException e) {
            System.err.println("Key Exception: Faulty key can not be used to sign signature." + " \n");
        } catch (KeyStoreException e) {
            System.err.println("KeyStore Exception: key Store may be faulty." + " \n");
……………

我尝试使用DscoreException,它可以根据对象的getLocalizedMessage()结果(不包括异常类名称)返回自定义描述性消息。 实现的要点是:

catch (Exception e) {
  throw new DscoreException(e);
} 
…………………..
class DscoreException extends Exception {
  DscoreException(Exception s) { 
        super(s.getLocalizedMessage());
        if (super.getLocalizedMessage().contains("Signature not available")) {
            System.err.println("Key Exception: Invalid key algorithm is used to sign signature." + " \n");
        }
}

它产生:

Key Exception: Invalid key algorithm is used to sign signature. 

Exception in thread "main" com.fc.security.DscoreException: SHA512withDSA Signature not available
    at com.fc.security.TestException.main(TestException.java:91)

我的期望是:

Key Exception: Invalid key algorithm is used to sign signature. 

如何仅显示我的自定义消息? (在else-if之后将有if

解决方法

您有一个异常,它会打印消息。那不是例外的工作。

应该认为异常可以提供足够的信息来描述其报告的异常。例如,它通常会有一个消息字符串。

如果某些代码捕获到该异常,则它可以(如果选择)显示消息字符串。但是Exception类永远不应该。

您的异常类应如下:

 class DSCoreException extends Exception {
      DSCoreException(String msg) {
          super(msg);
      }
      ... more needed here ...
 }

然后也许您有一个异常处理程序,用您自己的异常替换特定的异常。

  try {
      do_something_here();
  } 
  catch (Exception ex) {  // NOTE really ought to be a narrower class
      if (ex.getLocalizedMessage().contains("Signature not available"))             
          ex = new DSCoreException("Key Exception: Invalid key algorithm is used to sign signature."); 
      throw ex;
  }

您捕获到该异常,对其进行检查以查看其含义,并在重新引发该异常之前有选择地将其替换为更好的异常。

根据您的总体需求,略有不同:

  try {
      do_something_here();
  } 
  catch (Exception ex) {  // NOTE really ought to be a narrower class
      String msg = ex.getLocalizedMessage();
      if (msg.contains("Signature not available"))             
          msg = "Key Exception: Invalid key algorithm is used to sign signature."; 
      throw new DSCoreException(msg);
  }

那个总是抛出DSCoreException,但是可能替换消息。这样会将所有异常都转换为“您的”类,这对那些调用您代码的人可能都有好处。

这里的基础课是例外是控制流设备,而不仅仅是打印错误的东西。即使在您打算显示消息的简单情况下,异常也是一种将错误条件信息获取到将要显示该消息的代码的方法。例外本身不应该进行显示。

在现在删除的注释中提出的反对意见是,异常捕获器可以获取堆栈跟踪,从而揭示诸如程序包名称之类的信息。 OP显然想防止这种情况,尽管我不知道为什么。归结为希望异常行为不像异常一样。您无法以任何合理的方式进行控制。