J'écris un service Web en Java et j'essaie de trouver le meilleur moyen de définir les codes d'erreur et leurs chaînes d'erreur associées . J'ai besoin d'avoir un code d'erreur numérique et une chaîne d'erreur regroupés. Le code d'erreur et la chaîne d'erreur seront envoyés au client accédant au service Web. Par exemple, lorsqu'une exception SQLException se produit, je pourrais souhaiter effectuer les opérations suivantes:
// Example: errorCode = 1,
// errorString = "There was a problem accessing the database."
throw new SomeWebServiceException(errorCode, errorString);
Le programme client peut afficher le message:
"L'erreur n ° 1 s'est produite: un problème est survenu lors de l'accès à la base de données."
Ma première pensée a été d'utiliser l'un Enum
des codes d'erreur et de remplacer les toString
méthodes pour renvoyer les chaînes d'erreur. Voici ce que j'ai trouvé:
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
}
Ma question est la suivante: y a-t-il une meilleure façon de procéder? Je préférerais une solution dans le code, plutôt que de lire à partir d'un fichier externe. J'utilise Javadoc pour ce projet et il serait utile de pouvoir documenter les codes d'erreur en ligne et de les mettre à jour automatiquement dans la documentation.
Réponses:
Eh bien, il y a certainement une meilleure implémentation de la solution enum (qui est généralement assez agréable):
Vous pouvez remplacer toString () pour simplement renvoyer la description à la place - pas sûr. Quoi qu'il en soit, le point principal est que vous n'avez pas besoin de remplacer séparément pour chaque code d'erreur. Notez également que j'ai explicitement spécifié le code au lieu d'utiliser la valeur ordinale - cela facilite la modification de l'ordre et l'ajout / la suppression d'erreurs plus tard.
N'oubliez pas que ce n'est pas du tout internationalisé - mais à moins que votre client de service Web ne vous envoie une description des paramètres régionaux, vous ne pouvez pas l'internationaliser facilement de toute façon. Au moins, ils auront le code d'erreur à utiliser pour i18n côté client ...
la source
En ce qui me concerne, je préfère externaliser les messages d'erreur dans un fichier de propriétés. Ce sera vraiment utile en cas d'internationalisation de votre application (un fichier de propriétés par langue). Il est également plus facile de modifier un message d'erreur et il ne sera pas nécessaire de recompiler les sources Java.
Sur mes projets, j'ai généralement une interface qui contient des codes d'erreur (chaîne ou entier, peu importe), qui contient la clé dans les fichiers de propriétés pour cette erreur:
dans le fichier de propriétés:
Un autre problème avec votre solution est la maintenabilité: vous n'avez que 2 erreurs, et déjà 12 lignes de code. Alors imaginez votre fichier d'énumération alors que vous aurez des centaines d'erreurs à gérer!
la source
La surcharge de toString () semble un peu dégoûtante - cela semble un peu une extension de l'utilisation normale de toString ().
Qu'en est-il de:
me semble beaucoup plus propre ... et moins verbeux.
la source
Lors de mon dernier travail, je suis allé un peu plus loin dans la version enum:
@Error, @Info, @Warning sont conservés dans le fichier de classe et sont disponibles au moment de l'exécution. (Nous avons eu quelques autres annotations pour aider à décrire également la livraison des messages)
@Text est une annotation à la compilation.
J'ai écrit un processeur d'annotations pour cela qui a fait ce qui suit:
J'ai écrit quelques routines utilitaires qui ont aidé à consigner les erreurs, à les envelopper comme des exceptions (si vous le souhaitez) et ainsi de suite.
J'essaye de les amener à me laisser l'open-source ... - Scott
la source
Je vous recommande de jeter un œil à java.util.ResourceBundle. Vous devriez vous soucier de I18N, mais cela en vaut la peine même si vous ne le faites pas. Externaliser les messages est une très bonne idée. J'ai trouvé qu'il était utile de pouvoir donner une feuille de calcul aux gens d'affaires qui leur permettait de mettre dans la langue exacte qu'ils voulaient voir. Nous avons écrit une tâche Ant pour générer les fichiers .properties au moment de la compilation. Cela rend I18N trivial.
Si vous utilisez également Spring, tant mieux. Leur classe MessageSource est utile pour ce genre de choses.
la source
Juste pour continuer à fouetter ce cheval mort particulier, nous avons eu une bonne utilisation des codes d'erreur numériques lorsque des erreurs sont montrées aux clients finaux, car ils oublient ou lisent fréquemment le message d'erreur réel, mais peuvent parfois conserver et signaler une valeur numérique qui peut donner vous un indice de ce qui s'est réellement passé.
la source
Il existe de nombreuses façons de résoudre ce problème. Mon approche préférée est d'avoir des interfaces:
Vous pouvez maintenant définir n'importe quel nombre d'énumérations qui fournissent des messages:
Vous avez maintenant plusieurs options pour les transformer en chaînes. Vous pouvez compiler les chaînes dans votre code (en utilisant des annotations ou des paramètres de constructeur enum) ou vous pouvez les lire à partir d'un fichier de configuration / propriété ou d'une table de base de données ou d'un mélange. Cette dernière approche est mon approche préférée car vous aurez toujours besoin de messages que vous pourrez transformer en texte très tôt (c'est-à-dire pendant que vous vous connectez à la base de données ou que vous lisez la configuration).
J'utilise des tests unitaires et des frameworks de réflexion pour trouver tous les types qui implémentent mes interfaces pour m'assurer que chaque code est utilisé quelque part et que les fichiers de configuration contiennent tous les messages attendus, etc.
En utilisant des frameworks qui peuvent analyser Java comme https://github.com/javaparser/javaparser ou celui d'Eclipse , vous pouvez même vérifier où les énumérations sont utilisées et trouver celles qui ne sont pas utilisées.
la source
Moi (et le reste de notre équipe dans mon entreprise) préfère lever des exceptions au lieu de renvoyer des codes d'erreur. Les codes d'erreur doivent être vérifiés partout, transmis et ont tendance à rendre le code illisible lorsque la quantité de code augmente.
La classe d'erreur définirait alors le message.
PS: et se soucient aussi de l'internationalisation!
PPS: vous pouvez également redéfinir la méthode de montée et ajouter la journalisation, le filtrage, etc. si nécessaire (au moins dans les environnements, où les classes d'exception et les amis sont extensibles / modifiables)
la source
Un peu tard mais, je cherchais juste une jolie solution pour moi-même. Si vous avez un type d'erreur de message différent, vous pouvez ajouter une fabrique de messages simple et personnalisée afin de pouvoir spécifier plus de détails et de format que vous souhaitez plus tard.
EDIT: ok, utiliser enum ici est un peu dangereux car vous modifiez définitivement une énumération particulière. Je suppose que mieux serait de changer de classe et d'utiliser des champs statiques, mais que vous ne pouvez plus utiliser '=='. Donc je suppose que c'est un bon exemple de ce qu'il ne faut pas faire (ou ne le faire que lors de l'initialisation) :)
la source
enum pour le code d'erreur / la définition du message est toujours une bonne solution bien qu'elle ait un problème i18n. En fait, nous pouvons avoir deux situations: le code / message est affiché à l'utilisateur final ou à l'intégrateur système. Pour le dernier cas, I18N n'est pas nécessaire. Je pense que les services Web sont probablement le dernier cas.
la source
L'utilisation
interface
comme constante de message est généralement une mauvaise idée. Il s'infiltrera définitivement dans le programme client dans le cadre de l'API exportée. Qui sait, que les programmeurs clients ultérieurs pourraient analyser ces messages d'erreur (publics) dans le cadre de leur programme.Vous serez verrouillé pour toujours pour prendre en charge cela, car les changements de format de chaîne vont / peuvent interrompre le programme client.
la source
Veuillez suivre l'exemple ci-dessous:
};
Dans votre code, appelez-le comme:
la source
J'utilise PropertyResourceBundle pour définir les codes d'erreur dans une application d'entreprise afin de gérer les ressources de code d'erreur locales. C'est la meilleure façon de gérer les codes d'erreur au lieu d'écrire du code (cela peut être valable pour quelques codes d'erreur) lorsque le nombre de codes d'erreur est énorme et structuré.
Consultez la documentation java pour plus d'informations sur PropertyResourceBundle
la source