1. Contexte
L'article que j'ai écrit ici est parce qu'un ami a demandé quelle est la différence entre l'exception vérifiée et l'exception non contrôlée en Java. Ma réponse était: je n'utilise RuntimeException que lors de la programmation. En fait, j'ai une prémisse quand je dis quelque chose. Je devrais le dire exactement: je n'utilise ou ne prête pas attention à RuntimeException lors de la rédaction du code commercial dans un cadre de développement mature. Parce que, parce que les cadres résument souvent uniformément la gestion des exceptions, afin que les programmeurs puissent accorder une meilleure attention au code commercial, et certaines erreurs commerciales se produisent généralement pendant l'exécution du système, les exceptions commerciales sont généralement conçues comme des sous-classes de RuntimeException.
Ma réponse ne peut évidemment pas satisfaire mes amis! Parce que, peu importe qui est un débutant en Java, nous utilisons beaucoup d'essais ... Catch ... Quand nous apprenons les cours d'IO et la programmation JDBC, ce genre d'essai répété ... Catch nous fera nous souvenir des exceptions de Java! Les débutants ne savent souvent pas pourquoi les exceptions Java sont conçues comme celle-ci. Ils ne traitent généralement que les exceptions simplement - imprimez simplement les exceptions dans le bloc de capture, et la déclaration la plus couramment utilisée est:
E.PrintStackTrace ().
Nous avons également des exceptions telles que la mémoire telle que les limites de croisement de tableaux:
java.lang.arrayindexoutofboundSexception: 6
Cela nous fera également nous en souvenir frais, car il apparaît souvent lorsque nous déboglons le programme! Nous constatons que ce type d'exception n'a pas besoin d'utiliser Try ... Catch ... pour le prendre dans le code.
Les deux exemples ci-dessus sont en fait l'exception vérifiée et l'exception non contrôlée demandée par un ami. L'exception qui nécessite d'essayer ... Catch ... est l'exception vérifiée, et l'exception non contrôlée est l'exception non contrôlée. Si je veux parler de leurs différences, je dis que l'un d'eux veut essayer ... attraper ... et l'autre n'en a pas besoin. Cette réponse est-elle correcte? Je pense que cette réponse est pâle. Certains étudiants diront en outre que Try ... Catch est évidemment un appelant de méthode qui oblige l'exception à être explicitement gérée. E.PrintStackTrace () est-il considéré comme un traitement des exceptions? Je pense que c'est juste une façon simple et paresseuse de y faire face! Alors, quel type de méthode de manutention est considéré comme intelligent? Le concepteur de langue Java s'attend en fait qu'après une exception, l'appelant peut restaurer l'exception de la capture afin que le programme puisse continuer à s'exécuter. Cependant, "les programmeurs intelligents sont paresseux". Hehe. Dans la plupart des cas, nous choisissons d'enregistrer les journaux et les invites utilisateur de l'interface utilisateur après que l'exception apparaisse. Plus tard, je combinerai le framework Jersey pour parler de la manipulation des exceptions unifiées. Après avoir lu ceci, certaines personnes diront que la différence entre l'exception vérifiée et l'exception non contrôlée est que l'une doit être traitée et que l'autre n'a pas besoin d'être traitée. Cette réponse est-elle correcte? Je pense que c'est mal! Mon point est: nous devons y faire face, qu'il s'agisse d'une exception vérifiée ou d'une exception non contrôlée!
Dans le paragraphe précédent, nous ne semblions toujours pas résoudre la différence entre l'exception vérifiée et l'exception non contrôlée. Je ne pense pas qu'il soit important de donner la réponse. Ce qui est important, c'est la façon dont nous gérons ces exceptions et comment nous utilisons des exceptions pendant le développement.
Mon point est (développement du système Web):
1. Encapsulez l'exception vérifiée au niveau du cadre et convertissez-la en une exception non contrôlée pour éviter d'écrire des essais fastidieux ... Catch Code pendant le développement.
2.
3. Grâce aux deux premières vues, les exceptions personnalisées dans le système n'auront que des exceptions non contrôlées, et le système ne sera qu'à la couche supérieure du client échangeant des données, configurez un mécanisme de gestion des exceptions unifié et convertit certaines exceptions en informations que les utilisateurs peuvent comprendre et transmettre aux utilisateurs.
4. D'autres tels que la couche commerciale, la couche de persistance des données, etc., ne sont responsables que de lancer des exceptions, mais veillez à ne pas perdre la pile d'exception (c'est une erreur que les débutants sont susceptibles de faire).
L'arrière-plan est assez long! Passons au point et voyons comment le gestionnaire d'exceptions unifié du framework Jersey est utilisé!
2. Mécanisme de gestion des exceptions unifiée du cadre de Jersey
Il existe les accords suivants:
1. L'exemple utilise la version Jersey1.x
2. La version printanier est de 2,5
3. Pour plus de simplicité, l'échantillon de projet n'utilise pas le mécanisme Maven
Exemple de scénario commercial Description:
1. Nous lisons un fichier de configuration de propriétés, et le contenu du fichier de configuration est:
key1 = bonjour key2 = iteye.com
2. Démarrez une demande de get http: // localhost: 8888 / a / ressources / test? N = 11, nécessitant n être un nombre et doit être inférieur à 10. Si n est faux, une erreur d'exception non cochée sera générée.
3. Dans cet exemple, la couche d'accès aux données lira un fichier et une erreur d'exception vérifiée se produira si le fichier est lu.
Exemple de conception de structure de projet
Description de l'extrait de code
1. Fichier de stockage de données: test.properties
key1 = bonjour key2 = iteye.com
Il s'agit du fichier que nous voulons lire, et pour la simplicité, c'est un fichier de propriétés.
2. Classe d'accès aux données: testdao.java
package com.iteye.redhacker.jersey.dao; import java.io.ioexception; import java.io.inputstream; import java.net.url; importer java.util.properties; import org.springframework.sterreeotype.component; import com.iteye.redhacker.jersey.exception.comPonent; import. com.iteye.redhacker.jersey.exception.exceptioncode; @componentpublic class testDao {public String Sayshello () {classloader classloader = testdao.class.getClassloader (); string Inifile = "com / iteye / redhacker / jersey / dao / test.properties"; url = url = classloader.getResource (inifile); inputStream est; try {is = url.openStream ();} catch (ioException e) {throw new DaoException (e, exceptionCode.read_file_failed);} Propriétés appropriés = null; essai {if (approprié == NULL) {approprié = new Properties ();} correct.load (url.openStream ());} catch (ioException e) {throw new DaoException (e, exceptionCode.read_config_failed);} enfin {if (is! = Null) {try {is.cose (); is = nul Exceptioncode.colse_file_failed);}}} return propose.getProperty ("key1") + "," + correct.getProperty ("key2");}}Dans cette classe, toutes les exceptions vérifiées sont converties en exceptions incontrôlées (notre exception personnalisée). Lorsque vous appelez la méthode Sayhello (), essayez ... Catch ...
3. Classe d'implémentation commerciale: TestService.java
Package com.iteye.redhacker.jersey.service; import org.springframework.beans.factory.annotation.autowired; import org.springframework.sterreotype. com.iteye.redhacker.jersey.exception.serviceException; @ComponentPublic class TestService {@AutowiredPrivate testdao testdao; public string sayshello (int n) {// stipule business qui ne peut pas être plus grand que 10 if (n> 10) {lance un nouveau service (exceptioncode.mUst_be_fitch_10);}; testdao.sayhello ();} / ** * @param testdao le testdao pour définir * / public void SettestDao (testdao testdao) {this.testdao = testdao;}}Dans cette classe, nous lançons une exception commerciale qui est la nôtre, ce qui est une exception non contrôlée.
Remarque: nous avons injecté la classe TestDao en utilisant @Autowired, qui est une annotation fournie par Spring; Nous devons fournir une méthode définie pour annoter les attributs, sinon l'annotation échouera.
4. Demande la classe d'accès: TestResources.java
Package com.iteye.redhacker.jersey.delegate; import javax.ws.rs.get; import javax.ws.rs.path; import javax.ws.rs.produces; import javax.ws.rs.queryparam; import javax.ws.rs.core.Service.Service; import; com.sun.jersey.api.spring.autowire; @Path ("/ test") @ AutowirePublic Class TestResources {Private TestService TestService; @ get @ producies (mediaType.Text_PLAIN) Public String Sayshello (@QueryParam ("N") int n) {return TestService. TestService le test de test pour définir * / public void SettstService (testService TestService) {this.testService = TestService;}}Voici une ressource définie par Jersey. Nous pouvons accéder à cette ressource de cette manière: initier une demande GET, accéder à l'URI est / ressources / test et passer un paramètre de requête n, par exemple: / ressources / test? N = 1
Remarque: Nous avons utilisé @Autowire n'est pas une annotation pour le printemps, c'est une annotation pour le package d'intégration de jersey; Nous devons fournir une méthode définie pour annoter les attributs, sinon l'annotation échouera.
5. Classe Unified Excepte Handler: ExceptionMappersupport.java
package com.iteye.redhacker.jersey.jaxrs; import javax.servlet.servletContext; import javax.servlet.http.httpservletRequest; import javax.ws.rs.Core.context; import javax.ws.rs.core.mediaType; javax.ws.rs.core.response.status; import javax.ws.rs.ext.exceptionmapper; import javax.ws.rs.exxt.provider; import org.apache.log4j.logger; import org.springframework.web.context.webapplicationContext; import; com.iteye.redhacker.jersey.exception.baseexception; import com.iteye.redhacker.jersey.exception.exceptioncode; import com.sun.jersey.api.notfoundException; / ** * Unified Except Handler * / @ ProviderPublic Class Logger Logger = Logger Final Logger = Impléments exception Logger.getLogger (exceptionmappersupport.class); chaîne finale statique privée context_attribute = webApplicationContext.root_web_application_context_attribute; @contextprivate httpservletRequest request; @contextprivate servletcontext servletcontext; / ** * exception exception * * @param exception * TORESPONCE (exception exception) {String Message = exceptionCode.internal_server_error; status statuscode = status.internal_server_error; webApplicationContext context = (webApplicationContext) ServletContex BasEException.getcode (); objet [] args = BasEException.getValues (); Message = context.getMessage (code, args, exception.getMessage (), request.getlocale ());} else if (exception instanceOf NotfoundException) {Message = exceptionCode.request_not_found; statutCode = status.Not_found;} Les exceptions sont enregistrées dans le journal logger.Error (message, exception); return réponse.ok (message, mediatype.text_plain) .status (statuscode) .build ();}}Dans cette classe, nous gérons l'exception non contrôlée que nous avons définie, et traitons également des exceptions inconnues du système (y compris des exceptions inconnus et des exceptions vérifiées). Notre méthode de traitement est: a. Enregistrez le journal d'exception; né Envoyez un code d'erreur standard HTTP standard et un message d'erreur au client, et le client gère les informations d'erreur en soi. Il convient de noter que cette méthode de traitement est préconisée par REST et utilise de manière appropriée le code d'état standard HTTP;
Dans cette classe, nous utilisons également le composant de configuration international de Spring pour internationaliser la clé d'erreur lancée par le système, ce qui est propice à la mise à niveau de l'internationalisation de notre projet.
6. Classe de base d'exception personnalisée: BaseException.java
package com.iteye.redhacker.jersey.exception; / ** * Classe de base d'exception, les exceptions d'exécution de chaque module sont héritées de cette classe * / classe publique BasEEException étend RuntimeException {/ ** * Le SerialVersionUid * / privé static final SerialVeversionuid = 1381325479896057076l; / ** * Clé de message * / code de chaîne privé; / ** * Params de message * / objet privé [] valeurs; / ** * @return le code * / public String getCode () {return code; } / ** * @param code le code à définir * / public void setcode (String code) {this.code = code; } / ** * @return les valeurs * / objet public [] getValues () {return Values; } / ** * @param valeurs les valeurs à définir * / public void setValues (objet [] valeurs) {this.values = valeurs; } public BasEException (message de chaîne, cause thrognable, code de chaîne, objet [] valeurs) {super (message, cause); this.code = code; this.values = valeurs; }}Cette classe définit le modèle de base de la classe d'exception du projet, et d'autres exceptions en héritent. Il convient de noter qu'il utilise intelligemment certaines fonctionnalités de la configuration internationale et peut même lancer un message d'erreur défini ci-dessous et réutiliser le message d'erreur en passant par les paramètres:
{0} {1} Erreur des paramètres
7. D'autres exceptions sont fondamentalement les mêmes, mais les types sont différents. Jetons un coup d'œil à daoexception.java
Package com.iteye.redhacker.jersey.exception; classe publique DaoException étend BasEException {/ ** * Constructeurs * * @param code * Code d'erreur * / public daoException (code de chaîne) {super (code, null, code, null);} / ** * constructeurs * * @Param Cause * Exception Interface * @param code * Code d'erreur * / Public DaException (Cause * Code d'exception * @Param Code * Code d'erreur * {super (code, cause, code, null);} / ** * constructeurs * * @param code * code d'erreur * @param valeurs * un ensemble d'informations d'exception paramètres en instance * / public daoexception (code de chaîne, objet [] valeurs) {super (code, null, code, valeurs);} / ** * constructeurs * * @param cause d'interface d'exception * @param Code * Code d'erreur * Code d'erreur * @Param Values * A d'interface exception * Interface exception * Paramètres * / public daoException (Cause thrimpable, code de chaîne, objet [] VALEURS) {super (code, null, code, valeurs);} private static final SerialVersionUID = -3711290613973933714l;}Il hérite de BaseException. Lorsque cette exception est lancée, nous faisons directement des jugements préliminaires à partir du nom d'exception, et l'erreur provient de la couche DAO.
8. Errmsg.properties est utilisée pour définir les informations d'exception. Jetons un coup d'œil:
read.file.failed = read le fichier a échoué read.config.failed = read Configuration item échoué doit.be.less.than.10 = le paramètre doit être inférieur à 10colse.file.failed = reset fichier faillite.not.found = Le service correspondant n'a pas été trouvé interne.server.error = serveur Erroral Errord Errord Errory
Iii. Déploiement et test
Vous pouvez télécharger le code source dans la pièce jointe de cet article. Après l'importation d'Eclipse, vérifiez le code source.
Le déploiement est très simple, ajoutez simplement votre tomcat / config / server.xml:
<host> ... <
Commencez juste Tomcat!
Faites deux tests:
1 et 1
2
Pour le premier test, vous pouvez également voir l'erreur d'exception suivante dans le journal:
[2013-08-15 00:25:55] [Erreur] Le paramètre doit être inférieur à 10com.iteye.redhacker.jersey.exception.serviceException: must.be.less.Than.10at com.iteye.redhacker.jersey.service.testService.Sayhello (TestService.java:20) sur at com.iteye.redhacker.jersey.delegate.testResources.sayhello (TestResources.java:21) à Sun.Reflect.NativeMethodAccessorimpresorimpl.invoke (NativeMethodAccessorImpl.Java:39) Sun.Reflect.delegatingMethodAccessOrimpl.invoke (délégation deMethodAccessOrimpl.java:25) à java.lang.reflect.method.invoke (méthode.java:597) at com.sun.jersey.spi.continer.javamethodinvokerfactory 1 $ Invoke (javamethodinvokerfactory.java:60) à com.sun.jersey.spi.container.javamethodinvokerfactory 1,invoke (javaméthodinvokerfactory.java:60) à la com.sun.jersey.server.impl.model.method.dispatch.abstractreSourcethoddispatchProvider $ typeoutinvoker._dispatch (abstractreSourcethoddispatchProvider.java:185) à la com.sun.jersey.server.impl.model.method.dispatch.resourcejavamethoddispatcher.dispatch (ResourcejavameThoddispatcher.java:75) com.sun.jersey.server.impl.uri.rules.httpmethodrule.accept (httpmethodrule.java:288) à com.sun.jersey.server.impl.uri.rules.resourceclassrule.accept (ResourceclassRule.java:108) at at at at a com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) at com.sun.jersey.server.implantation.webappcationimpl._handlerequest (webapplicationmpl.java:1483) sur com.sun.jersey.server.implication.application.webapplicationImpl._handleequest (webapplicationmplat.java:1414) sur at com.sun.jersey.server.implantation.webappcationImpl.handlerequest (webApplicationImpl.java:1363) sur com.sun.jersey.server.implantation.webapplicationImpl.handlerequest (webApplicationImpl.java:1353)
Pour d'autres tests, vous pouvez l'essayer, comme la suppression délibérément des tests. Lorsque le fichier à lire ne peut être trouvé, comment l'exception vérifiée est convertie en une exception non contrôlée auto-définie et les enregistre, renvoyant le code d'état d'erreur HTTP standard et les informations d'erreur au client.
4. Résumé
1. Il n'est pas difficile de voir à travers le cadre de Jersey que dans le développement de projets Web, nous avons géré l'exception vérifiée et l'exception non contrôlée aussi uniformément que possible au niveau du cadre afin que nous puissions accorder plus d'attention à la mise en œuvre de l'entreprise.
2. S'il s'agit d'un projet non Web, je pense que le concepteur d'architecture de programme devrait également essayer de gérer les exceptions uniformément; S'il n'est pas géré uniformément, lorsqu'une exception vérifiée est rencontrée, nous devons le gérer de manière appropriée, au lieu de simplement faire un e.printStackTrace (); Si nous ne pouvons pas récupérer l'exception, nous devons au moins enregistrer les informations d'erreur de l'exception complètement dans le fichier journal afin que les erreurs soient vérifiées lorsque les programmes suivants échouent.
Texte complet (fin)