Ich schreibe einen Webdienst in Java und versuche herauszufinden, wie Fehlercodes und die zugehörigen Fehlerzeichenfolgen am besten definiert werden können . Ich brauche einen numerischen Fehlercode und eine Fehlerzeichenfolge, die zusammen gruppiert sind. Sowohl der Fehlercode als auch die Fehlerzeichenfolge werden an den Client gesendet, der auf den Webdienst zugreift. Wenn beispielsweise eine SQLException auftritt, möchte ich möglicherweise Folgendes tun:
// Example: errorCode = 1,
// errorString = "There was a problem accessing the database."
throw new SomeWebServiceException(errorCode, errorString);
Dem Client-Programm wird möglicherweise die folgende Meldung angezeigt:
"Fehler Nr. 1 ist aufgetreten: Beim Zugriff auf die Datenbank ist ein Problem aufgetreten."
Mein erster Gedanke war, einen Enum
der Fehlercodes zu verwenden und die toString
Methoden zum Zurückgeben der Fehlerzeichenfolgen zu überschreiben . Folgendes habe ich mir ausgedacht:
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
}
Meine Frage ist: Gibt es einen besseren Weg, dies zu tun? Ich würde eine Lösung im Code vorziehen, anstatt aus einer externen Datei zu lesen. Ich verwende Javadoc für dieses Projekt, und es wäre hilfreich, die Fehlercodes online zu dokumentieren und sie automatisch in der Dokumentation aktualisieren zu lassen.
Antworten:
Nun, es gibt sicherlich eine bessere Implementierung der Enum-Lösung (was im Allgemeinen recht nett ist):
Möglicherweise möchten Sie toString () überschreiben, um stattdessen nur die Beschreibung zurückzugeben - nicht sicher. Der wichtigste Punkt ist jedoch, dass Sie nicht für jeden Fehlercode separat überschreiben müssen. Beachten Sie auch, dass ich den Code explizit angegeben habe, anstatt den Ordnungswert zu verwenden. Dies erleichtert das spätere Ändern der Reihenfolge und das Hinzufügen / Entfernen von Fehlern.
Vergessen Sie nicht, dass dies überhaupt nicht internationalisiert ist - aber wenn Ihr Webdienst-Client Ihnen keine Gebietsschemabeschreibung sendet, können Sie diese ohnehin nicht einfach selbst internationalisieren. Zumindest haben sie den Fehlercode für i18n auf der Clientseite ...
quelle
Ich bevorzuge es, die Fehlermeldungen in einer Eigenschaftendatei zu externalisieren. Dies ist im Falle einer Internationalisierung Ihrer Anwendung sehr hilfreich (eine Eigenschaftendatei pro Sprache). Es ist auch einfacher, eine Fehlermeldung zu ändern, und die Java-Quellen müssen nicht neu kompiliert werden.
In meinen Projekten habe ich im Allgemeinen eine Schnittstelle, die Fehlercodes enthält (String oder Integer, es ist nicht wichtig), die den Schlüssel in den Eigenschaftendateien für diesen Fehler enthält:
in der Eigenschaftendatei:
Ein weiteres Problem bei Ihrer Lösung ist die Wartbarkeit: Sie haben nur 2 Fehler und bereits 12 Codezeilen. Stellen Sie sich also Ihre Aufzählungsdatei vor, wenn Sie Hunderte von Fehlern verwalten müssen!
quelle
Das Überladen von toString () scheint ein bisschen schwierig zu sein - das scheint ein bisschen ein Teil der normalen Verwendung von toString () zu sein.
Wie wäre es mit:
scheint mir viel sauberer zu sein ... und weniger ausführlich.
quelle
Bei meinem letzten Job bin ich etwas tiefer in die Enum-Version gegangen:
@Error, @Info, @Warning bleiben in der Klassendatei erhalten und sind zur Laufzeit verfügbar. (Wir hatten noch ein paar andere Anmerkungen, um die Zustellung von Nachrichten zu beschreiben.)
@Text ist eine Annotation zur Kompilierungszeit.
Ich habe dafür einen Anmerkungsprozessor geschrieben, der Folgendes tat:
Ich habe einige Dienstprogramme geschrieben, mit denen Fehler protokolliert, als Ausnahmen (falls gewünscht) usw. verpackt werden konnten.
Ich versuche, sie dazu zu bringen, mich Open Source zu machen ... - Scott
quelle
Ich würde empfehlen, dass Sie sich java.util.ResourceBundle ansehen. Sie sollten sich für I18N interessieren, aber es lohnt sich, auch wenn Sie es nicht tun. Das Externalisieren der Nachrichten ist eine sehr gute Idee. Ich habe festgestellt, dass es nützlich war, Geschäftsleuten eine Tabelle zu geben, in der sie genau die Sprache eingeben konnten, die sie sehen wollten. Wir haben eine Ant-Task geschrieben, um die .properties-Dateien zur Kompilierungszeit zu generieren. Das macht I18N trivial.
Wenn Sie auch Spring verwenden, umso besser. Ihre MessageSource-Klasse ist für diese Art von Dingen nützlich.
quelle
Nur um dieses tote Pferd weiter auszupeitschen - wir haben numerische Fehlercodes gut verwendet, wenn Endkunden Fehler angezeigt werden, da sie häufig die tatsächliche Fehlermeldung vergessen oder falsch lesen, aber manchmal einen numerischen Wert beibehalten und melden, der angeben kann Sie ein Hinweis darauf, was tatsächlich passiert ist.
quelle
Es gibt viele Möglichkeiten, dies zu lösen. Mein bevorzugter Ansatz ist es, Schnittstellen zu haben:
Jetzt können Sie eine beliebige Anzahl von Aufzählungen definieren, die Nachrichten bereitstellen:
Jetzt haben Sie mehrere Möglichkeiten, diese in Strings umzuwandeln. Sie können die Zeichenfolgen in Ihren Code kompilieren (mithilfe von Anmerkungen oder Enum-Konstruktorparametern) oder sie aus einer Konfigurations- / Eigenschaftendatei oder aus einer Datenbanktabelle oder einer Mischung lesen. Letzteres ist mein bevorzugter Ansatz, da Sie immer einige Nachrichten benötigen, die Sie sehr früh (dh währenddessen) in Text umwandeln können Sie eine Verbindung zur Datenbank herstellen oder die Konfiguration lesen).
Ich verwende Unit-Tests und Reflection-Frameworks, um alle Typen zu finden, die meine Schnittstellen implementieren, um sicherzustellen, dass jeder Code irgendwo verwendet wird und dass die Konfigurationsdateien alle erwarteten Nachrichten usw. enthalten.
Mit Frameworks, die Java analysieren können, wie https://github.com/javaparser/javaparser oder dem von Eclipse , können Sie sogar überprüfen, wo die Aufzählungen verwendet werden, und nicht verwendete finden.
quelle
Ich (und der Rest unseres Teams in meinem Unternehmen) ziehe es vor, Ausnahmen auszulösen, anstatt Fehlercodes zurückzugeben. Fehlercodes müssen überall überprüft, weitergegeben und dazu neigen, den Code unlesbar zu machen, wenn die Codemenge größer wird.
Die Fehlerklasse würde dann die Nachricht definieren.
PS: und eigentlich auch für die Internationalisierung sorgen!
PPS: Sie können die Raise-Methode auch neu definieren und bei Bedarf Protokollierung, Filterung usw. hinzufügen (zumindest in Umgebungen, in denen die Ausnahmeklassen und Freunde erweiterbar / änderbar sind).
quelle
Ein bisschen spät, aber ich suchte nur nach einer hübschen Lösung für mich. Wenn Sie eine andere Art von Nachrichtenfehler haben, können Sie eine einfache, benutzerdefinierte Nachrichtenfactory hinzufügen, damit Sie später weitere Details und Formate angeben können.
EDIT: ok, die Verwendung von enum hier ist ein wenig gefährlich, da Sie bestimmte enum dauerhaft ändern. Ich denke, es wäre besser, zur Klasse zu wechseln und statische Felder zu verwenden, aber dann können Sie '==' nicht mehr verwenden. Ich denke, es ist ein gutes Beispiel dafür, was nicht zu tun ist (oder nur während der Initialisierung) :)
quelle
Die Aufzählung für die Definition von Fehlercode / Nachricht ist immer noch eine gute Lösung, obwohl sie ein i18n-Problem hat. Tatsächlich können zwei Situationen auftreten: Der Code / die Nachricht wird dem Endbenutzer oder dem Systemintegrator angezeigt. Für den späteren Fall ist I18N nicht erforderlich. Ich denke, die Webdienste sind höchstwahrscheinlich der spätere Fall.
quelle
Verwenden von
interface
als Nachrichtenkonstante ist im Allgemeinen eine schlechte Idee. Es wird als Teil der exportierten API dauerhaft in das Client-Programm gelangen. Wer weiß, dass spätere Client-Programmierer diese (öffentlichen) Fehlermeldungen möglicherweise als Teil ihres Programms analysieren.Sie werden für immer gesperrt sein, um dies zu unterstützen, da Änderungen im Zeichenfolgenformat das Client-Programm beschädigen können / können.
quelle
Bitte folgen Sie dem folgenden Beispiel:
};
Nennen Sie es in Ihrem Code wie folgt:
quelle
Ich verwende PropertyResourceBundle, um die Fehlercodes in einer Unternehmensanwendung zu definieren, um lokale Fehlercode-Ressourcen zu verwalten. Dies ist der beste Weg, um mit Fehlercodes umzugehen, anstatt Code zu schreiben (kann für wenige Fehlercodes gelten), wenn die Anzahl der Fehlercodes sehr groß und strukturiert ist.
Weitere Informationen zu PropertyResourceBundle finden Sie im Java-Dokument
quelle