1。背景
私がここで書いた記事は、友人がJavaでのチェックされた例外と未確認の例外の違いを尋ねたからです。それに対する私の答えは、プログラミング時にのみruntimeexceptionを使用しています。実際、私が何かを言うとき、私は前提を持っています。私はそれを正確に言うべきです:私は、成熟した開発フレームワークの下でビジネスコードを書くときにのみruntimeexceptionに使用または注意を払うことです。なぜなら、フレームワークは多くの場合、例外処理を均一にカプセル化しているため、プログラマーがビジネスコードにもっと注意を払うことができ、通常はシステムの実行中にいくつかのビジネスエラーが発生するため、ビジネスの例外は通常、runtimeexceptionのサブクラスとして設計されています。
私の答えは明らかに私の友達を満足させることはできません!なぜなら、Javaの初心者であっても、私たちは多くの試みを使用しています... CATCH ... IOクラスとJDBCプログラミングを学ぶとき、この種の繰り返しの試行...キャッチはJavaの例外を覚えています!初心者は、Javaの例外がこのように設計されている理由を知らないことがよくあります。彼らは通常、例外のみを処理するだけです - 単にキャッチブロックで例外を印刷するだけで、最も一般的に使用されるステートメントは次のとおりです。
e.printstacktrace()。
また、配列の交差境界などのメモリなどの例外もあります。
Java.lang.ArrayIndexOutofBoundSexception:6
また、これにより、プログラムをデバッグするときによく表示されるため、新鮮に覚えておくことができます!このタイプの例外は、コードでキャッチするためにtry ... catch ... catch ...を使用する必要がないことがわかります。
上記の2つの例は、実際には、友人から尋ねられたチェックされた例外と未確認の例外です。試してみる必要がある例外...キャッチ...はチェックされた例外であり、チェックされていない例外は未チェックの例外です。私が彼らの違いについて話したいなら、私は彼らのうちの1つが試してみたいと言います...キャッチ...そしてもう1つはそれを必要としません。この答えは大丈夫ですか?この答えは青白いと思います。一部の学生はさらに、試してみる...キャッチは明らかに、例外を明示的に処理することを強制するメソッド呼び出し者であると言うでしょう。 e.printstacktrace()は処理の例外を考慮していますか?それはそれに対処するためのシンプルで怠zyな方法だと思います!では、どのような処理方法が賢いと考えられていますか? Java Language Designerは、実際に例外が発生した後、発信者がプログラムを実行し続けることができるように、キャッチ内の例外を復元できることを期待しています。しかし、「スマートプログラマーは怠け者です。」 hehe。ほとんどの場合、例外が表示された後、ログとUIユーザープロンプトを記録することを選択します。その後、ジャージーフレームワークを組み合わせて、統一された例外処理について説明します。これを読んだ後、一部の人々は、チェックされた例外と未確認の例外の違いは、一方を処理する必要があり、もう1つを処理する必要がないということです。この答えは正しいですか?間違っていると思います!私のポイントは、それがチェックされた例外であろうとチェックされていない例外であろうと、それに対処しなければならないということです!
前の段落では、チェックされた例外とチェックされていない例外の違いを解決していないようです。答えを与えることは重要ではないと思います。重要なのは、これらの例外をどのように処理するか、そして開発中に例外を使用する方法です。
私のポイントは(Webシステム開発)です:
1.フレームワークレベルでチェックされた例外をカプセル化し、それを未確認の例外に変換して、退屈な試行を避けないでください...開発中にコードをキャッチします。
2。ビジネスレベルの開発は、プログラムコードの責任に従って異なるruntimeexceptionsを定義します(これは、一般にruntimexceptionのサブクラスとして定義されている未チェックの例外です)
3.最初の2つのビューを通じて、システムのカスタム例外は未チェックの例外のみを持ち、システムはクライアントの上部層にのみデータを交換し、統一された例外処理メカニズムを設定し、ユーザーがユーザーに理解して伝えることができる情報にいくつかの例外を変換します。
4.ビジネスレイヤー、データ永続性レイヤーなどのその他は、例外を投げることのみを担当しますが、例外スタックを失わないように注意してください(これは初心者が作る傾向がある間違いです)。
背景は十分に長いです!ポイントに到達して、ジャージーフレームワークの統一された例外ハンドラーがどのように使用されているかを見てみましょう!
2。ジャージーフレームワークの統一例外処理メカニズム
次の契約があります。
1.この例では、Jersey1.xバージョンを使用しています
2。スプリングバージョンは2.5です
3。簡単にするために、サンプルプロジェクトはMavenメカニズムを使用しません
例ビジネスシナリオ説明:
1.プロパティ構成ファイルを読み取り、構成ファイルのコンテンツは次のとおりです。
key1 = hello key2 = iteye.com
2. GETリクエストを開始http:// localhost:8888/a/resources/test?n = 11、nが数値であり、10未満でなければならない必要があります。nが間違っている場合は、未チェックの例外エラーが生成されます。
3。この例では、データアクセスレイヤーがファイルを読み取り、ファイルが読み取られるとチェックされた例外エラーが発生します。
サンプルプロジェクト構造設計
コードスニペットの説明
1。データストレージファイル:test.properties
key1 = hello key2 = iteye.com
これは読みたいファイルであり、簡単にするためにプロパティファイルです。
2。データアクセスクラス:testdao.java
パッケージcom.itey.redhacker.jersey.dao; Import java.io.ioexception; Import java.io.inputstream; Import java.net.url; Import java.util.properties; import org.springframework.stereototy.component; import com.redhacker.jersex.daesey. com.itey.redhacker.jersey.exception.excepticcode; @componentpublic class testdao {public string sayshello(){classloader classoloader = testdao.class.getClassoloder(); string inifile = "com/iteye/redhacker/jersy/dao/test.properties"; classloader.getResource(infile); inputstream is; try {is = url.openstream();} catch(ioexception e){show new daoexception(e、exceptioncode.read_file_failed) catch(ioexception e){new daoexception(e、exceptioncode.read_config_failed);}最後に{if(is!= null){try {is.close(); ais = null;} catch(ioexception e){新しいdaoexception(e、excementscode.code_filed_fileded); proper.getProperty( "key1") + "、" + proper.getProperty( "key2");}}}このクラスでは、すべてのチェックされた例外が未確認の例外に変換されます(カスタム例外)。 sayhello()メソッドを呼び出すとき、試してみてください...キャッチ...
3。ビジネス実装クラス:testservice.java
パッケージcom.itee.redhacker.jersey.service; Import org.springframework.beans.factory.annotation.autowired; Import org.springframework.stereotype.component; import com.itey.iety.redhacker.jesey.dao.testdao; Import com.itey.redhacker.jersey.exception.exceptode; Import com.itey.itey.redhacker.jersey.exception.serviceException; @componentpublic class testservice {@autowiredprivate testdao testdao; public String sakeshello(int n) serviceException(exceptioncode.must_be_less_than_10);} return testdao.sayhello();}/** * @param testdao testdao to set */public void settestdao(testdao testdao){this.testdao = testdao;}}}このクラスでは、私たち自身のビジネス例外を投げかけます。これは未確認の例外です。
注: @autowiredを使用してtestdaoクラスを注入しました。これは、春が提供する注釈です。属性に注釈を付けるための設定された方法を提供する必要があります。そうしないと、注釈が失敗します。
4.アクセスクラスをリクエスト:testresources.java
パッケージ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.Mediatype; com.sun.jersey.api.spring.autowire; @path( "/test")@autowirepublic class testresources {private testservice testservice;@get@produces(mediatype.text_plain)public string sayshello(@queryparam( "n")int n) testService testServiceを設定する */public void SettestService(testService testService){this.testService = testService;}}}ジャージーが定義したリソースは次のとおりです。この方法でこのリソースにアクセスできます。GETリクエストを開始し、URI IS /リソース /テストにアクセスし、クエリパラメーターnを渡します。例: /リソース /テスト?n = 1
注:@Autowireは春の注釈ではなく、ジャージースング統合パッケージの注釈です。属性に注釈を付けるための設定された方法を提供する必要があります。そうしないと、注釈が失敗します。
5。統一された例外ハンドラークラス:ExceptionMappersupport.java
パッケージcom.itee.redhacker.jersey.jaxrs; import javax.servlet.servletcontext; import javax.servlet.http.httpservletrequest; import javax.ws.rs.core.context; import javax.ws.rs.rs.rrespe; import; javax.ws.rs.core.response.status; Import javax.ws.Rs.ext.exceptionMapper; Import javax.ws.rs.ext.provider; Import org.apache.log4j.logger; import org.springframework.web.web.context.webapplicationcontext; Import; com.itey.redhacker.jersey.exception.baseexcection; Import com.itey.edhacker.jersey.exception.exceptioncode; Import com.sun.jersey.api.notfoundexception; logger.getLogger(ExceptionMappersupport.class); private static final string context_attribute = webapplicationcontext.root_web_application_context_attribute; @contextprivate httpservletrequest request;処理*/public Response Toresponse(例外例外){文字列メッセージ= exceptionCode.internal_server_error; status statuscode = status.internal_server_error; webapplicationcontext context =(webapplicationcontext)servletcontext.getattribute(context_attribute(context_attribute); (baseexception)exception; string code = baseexception.getCode(); object [] args = baseexception.getValues(); message = context.getMessage(code、args、exception.getMessage()、request.getLocale()); status.not_found;} //チェックされた例外と未チェックの例外は、logger.error(メッセージ、例外)に記録されています。 return Response.ok(message、mediatype.text_plain).status(statuscode).build();}}}}このクラスでは、定義した未確認の例外を処理し、システムの未知の例外(未知の未チェックの例外とチェックされた例外を含む)も処理します。処理方法は次のとおりです。例外ログを記録します。 b。標準のHTTP標準エラーステータスコードとエラーメッセージをクライアントに送信すると、クライアントはエラー情報を単独で処理します。この処理方法はRESTによって提唱されており、HTTP標準ステータスコードを適切に使用していることは注目に値します。
このクラスでは、SpringのInternational Configurationコンポーネントを使用して、プロジェクトの国際化のアップグレードを助長するシステムによってスローされたエラーキーを国際化します。
6。カスタム例外ベースクラス:baseexception.java
パッケージcom.itey.redhacker.jersey.exception;/***例外ベースクラス、各モジュールのランタイム例外はこのクラスから継承されます*/public class baseexceptionはruntimeexception {/***/private static final long serialversionuid = 138132547996057076l; / ** *メッセージキー */プライベート文字列コード。 / ** *メッセージparams */ private object [] values; / ** * @return code */ public string getCode(){return Code; } / ** * @paramコードを設定するコード * / public void setCode(string code){this.code = code; } / *** @return値* / public object [] getValues(){return値; } / ** * @param値は、値を設定する値を値 * / public void setValues(object [] values){this.values = values; } public baseexception(string message、throwable cause、string code、object [] values){super(message、cause); this.code = code; this.values = values; }}このクラスは、プロジェクト例外クラスの基本的なテンプレートを定義し、その他の例外はそれから継承されます。国際的な構成のいくつかの機能を巧みに利用し、以下に定義したエラーメッセージを投げることもでき、パラメーターを渡すことでエラーメッセージを再利用することもできることに注意してください。
{0} {1}パラメーターエラー
7.他の例外は基本的に同じですが、タイプは異なります。 daoexception.javaを見てみましょう
パッケージcom.itey.redhacker.jersey.exception; public class daoexceptionはbaseexceptionを拡張します{/** *コンストラクター * * @paramコード *エラーコード */public daoexception(string code){super(code、null、null、null、null、null);}/** * @param courdable courd * courd */public code */public deable * * {super(code、code、code、null);}/** * constructors * * @param code *エラーコード * @param values * @param values * public daoexception(string code、object [] values){super(code、null、code、values);}/** * @param constracts * @param code * @param corde * @param cordes * @param constractors * * ** * ** * ** * ** *パラメーター */public daoexception(スロー可能な原因、文字列コード、オブジェクト[]値[]値){super(code、null、code、values);} private static final long serialversionuid = -3711290613973933714l;}それはbaseexceptionを継承します。この例外がスローされると、例外名から予備的な判断を直接行い、エラーはDAOレイヤーから発生します。
8。ERRMSG.Propertiesは、例外情報を定義するために使用されます。見てみましょう:
read.file.failed = read file fail failed read.config.failed = read configuration itequired must.be.less.than.10 =パラメーターは10colse.file.failed = reset file failed request.not.found.found.found = internal.server.error.error =サーバー内部エラー
iii。展開とテスト
この記事の添付ファイルでソースコードをダウンロードできます。 Eclipseをインポートした後、ソースコードを確認してください。
展開は非常に簡単です。Tomcat/config/server.xmlを追加するだけです。
<host> ... <Context Path = "/a" reloadable = "true" docbase = "d:/workspace/test/jerseyexceptionmappertest/web"/> </host>
Tomcatを始めてください!
2つのテストを実行します。
1。
2。
最初のテストでは、ログに次の例外エラーを確認できます。
[2013-08-15 00:25:55] [エラー]パラメーターは10com.itey.redhacker.jersey.exception.serviceexception:bed.be.than.10at com.itey.redhacker.jersey.service.testservice.ayhello(テストservice.jaiava :10)である必要があります。 com.itey.redhacker.jersey.delegate.testresources.sayhello(testresources.java:21)at sun.reflect.nativemethodaccessorimpl.invoke0(native method)at sun.reflt.nativemethodaccessimpl.invoke sun.reflt.delegatingmethodaccessorimpl.invoke(DelegatingMethodaccessorimpl.java:25)at java.lang.reflt.method.invoke(method.java:597)at com.sun.jersey.spi.container.javamethodinvokeractory $ 1. invoke(javamethodinvokeractory.java:60)at com.sun.jersey.spi.container.javamethodinvokeractory $ 1.invoke com.sun.jersey.server.impl.model.method.dispatch.abstractresourcemethoddispatchprovider $ typeoutinvoker._dispatch(abstractresourcemethoddispatchprovider.java:185) com.sun.jersey.server.impl.model.method.dispatch.resourcejavamethoddispatcher.dispatch(resourcejavamethodddispatcher.java:75)at com.sun.jersey.server.impl.uri.rules.httpmethodrule.accept(httpmethodrule.java:288)com.sun.jersey.server.impl.uri.rules.resourcelassrule.cectic(Resourclule.Java:108) com.sun.jersey.server.impl.uri.rules.righthandpathrule.accept(righthandpathrule.java:147)at com.sun.jersey.server.impl.uri.rules.RootResourceClassESRule.ut com.sun.jersey.server.impl.application.webapplicationimpl._handlerequest(webapplicationimpl.java:1483)at com.sun.jersey.server.impl.Application.webapplicationimpl._handLerequest(webApplisionimplicationimpl.java:1414) com.sun.jersey.server.impl.application.webapplicationimpl.handlerequest(webapplicationimpl.java:1363)at com.sun.jersey.server.impl.application.webapplicationimpl.handlerequest(webapplicationImpl.java:1353)
他のテストでは、Test.Propertiesを意図的に削除するなど、試してみることができます。読み取るファイルが見つからない場合、チェックされた例外が自己定義された未チェックの例外に変換され、それを記録する方法を記録し、標準のHTTPエラーステータスコードとエラー情報をクライアントに返します。
4。概要
1. Jersey Frameworkを通して、Webプロジェクト開発では、チェックされた例外と未確認の例外をフレームワークレベルでできるだけ均一に処理し、ビジネスの実装により多くの注意を払うことができることを確認することは難しくありません。
2.それが非WEBプロジェクトの場合、プログラムアーキテクチャデザイナーは例外を均一に処理しようとする必要があると思います。均一に処理されていない場合、チェックされた例外が発生した場合、E.PrintStackTrace()を単に実行する代わりに、適切に処理する必要があります。例外を回復できない場合は、後続のプログラムが失敗したときにエラーがチェックされるように、ログファイルに例外のエラー情報を少なくとも完全に記録する必要があります。
全文(終了)