我正在用Java编写Web服务,我试图找出定义错误代码及其相关错误字符串的最佳方法.我需要将数字错误代码和错误字符串组合在一起.错误代码和错误字符串都将发送到访问Web服务的客户端.例如,当发生SQLException时,我可能想要执行以下操作:
// Example: errorCode = 1, // errorString = "There was a problem accessing the database." throw new SomeWebServiceException(errorCode, errorString);
客户端程序可能会显示以下消息:
"发生错误#1:访问数据库时出现问题."
我的第一个想法是使用Enum
错误代码并覆盖toString
方法以返回错误字符串.这是我想出的:
public enum Errors { DATABASE { @Override public String toString() { return "A database error has occured."; } }, DUPLICATE_USER { @Override public String toString() { return "This user already exists."; } }, // more errors follow }
我的问题是:有更好的方法吗?我更喜欢代码中的解决方案,而不是从外部文件读取.我在这个项目中使用Javadoc,并且能够在线记录错误代码并在文档中自动更新它们会很有帮助.
那么enum解决方案肯定有更好的实现(通常非常好):
public enum Error { DATABASE(0, "A database error has occured."), DUPLICATE_USER(1, "This user already exists."); private final int code; private final String description; private Error(int code, String description) { this.code = code; this.description = description; } public String getDescription() { return description; } public int getCode() { return code; } @Override public String toString() { return code + ": " + description; } }
您可能希望覆盖toString()以仅返回描述 - 不确定.无论如何,重点是您不需要为每个错误代码单独覆盖.另请注意,我已明确指定代码而不是使用序数值 - 这样可以更轻松地更改顺序并在以后添加/删除错误.
不要忘记这根本不是国际化的 - 但除非您的Web服务客户端向您发送区域设置描述,否则无论如何都无法轻易地将其国际化.至少他们会在客户端使用i18n的错误代码......
就我而言,我更喜欢将属性文件中的错误消息外部化.这对于应用程序的国际化(每种语言一个属性文件)非常有用.修改错误消息也更容易,并且不需要重新编译Java源代码.
在我的项目中,通常我有一个包含错误代码的接口(字符串或整数,它并不关心),其中包含此错误的属性文件中的键:
public interface ErrorCodes { String DATABASE_ERROR = "DATABASE_ERROR"; String DUPLICATE_USER = "DUPLICATE_USER"; ... }
在属性文件中:
DATABASE_ERROR=An error occurred in the database. DUPLICATE_USER=The user already exists. ...
您的解决方案的另一个问题是可维护性:您只有2个错误,并且已经有12行代码.想象一下,当你需要管理数百个错误时,你的Enumeration文件!
重载toString()似乎有点icky - 这似乎是toString()正常使用的一小部分.
关于什么:
public enum Errors { DATABASE(1, "A database error has occured."), DUPLICATE_USER(5007, "This user already exists."); //... add more cases here ... private final int id; private final String message; Errors(int id, String message) { this.id = id; this.message = message; } public int getId() { return id; } public String getMessage() { return message; } }
对我来说似乎更清洁......而且不那么冗长.
在我上一份工作中,我在enum版本中更深入了一些:
public enum Messages { @Error @Text("You can''t put a {0} in a {1}") XYZ00001_CONTAINMENT_NOT_ALLOWED, ... }
@ Error,@ Info,@ Warning保留在类文件中,并在运行时可用.(我们还有一些其他注释来帮助描述消息传递)
@Text是一个编译时注释.
我为此编写了一个注释处理器,它执行了以下操作:
验证没有重复的消息编号(第一个下划线之前的部分)
语法 - 检查消息文本
生成一个messages.properties文件,其中包含由枚举值键入的文本.
我编写了一些实用程序例程来帮助记录错误,将它们包装为异常(如果需要)等等.
我试图让他们让我开源...... - 斯科特
我建议你看一下java.util.ResourceBundle.你应该关心I18N,但即使你不这样做也是值得的.外化消息是一个非常好的主意.我发现能够向业务人员提供一个电子表格是很有用的,这些人员可以使用他们希望看到的确切语言.我们编写了一个Ant任务来在编译时生成.properties文件.它使I18N变得微不足道.
如果你也使用Spring,那就更好了.他们的MessageSource类对于这些类型的东西很有用.