2011-07-03 5 views
8

私のSpring MVCのアプリは、次のようになり方法がいっぱいです:Spring MVCアプリケーションで例外ログを例外処理に変更する最も簡単な方法は何ですか?

@RequestMapping(value = "/foo", method = RequestMethod.GET) 
public final void foo(HttpServletRequest request, ModelMap modelMap){ 
    try{ 
     this.fooService.foo(); 
    } 
    catch (Exception e){ 
     log.warn(e.getMessage(), e); 
    } 
} 

例外がキャッチされ、記録され、それ以外は処理されません。

上記のfooServiceは、コントローラーまで例外をスローせず、キャッチしてログに記録するという同じことを行います。したがって、実際にはこのコントローラ例外コードは呼び出されません。

私のアプリで適切な例外処理を実装するための最も簡単で簡単なアプローチは何ですか?

答えて

9

すべてがcatchステートメントを取り除くのは、不注意でログに記録されている場合です。 catchは、エラーを隠すのではなく、エラーを処理するためのものです。これらすべての漁獲量が削除されたら

、Spring MVCの(123、...)に1つのグローバル例外リゾルバをインストールするだけで、この些細なインターフェイスを実装:あなたの例外リゾルバで

public interface HandlerExceptionResolver { 
    ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex); 
} 

を、あなたは単にかもしれません例外を一度ログに記録し、未処理のままにしておくと(null)、エラーマッピングがweb.xmlになり、適切なエラーページにリクエストが転送されます。または、自分で例外を処理してエラーページを表示することもできます。 AFAIKの最も単純なケースでは、レジスタ例外リゾルバの必要はありません。ちょうどそれを@ServiceでSpring bean/annotateとして定義してください。

対処方法が分かっている場合にのみ例外をキャッチしてください。ロギングはトラブルシューティングのためだけであり、何も処理しません。

ところで、この:

log.warn(e.getMessage(), e); 

は非常に悪い例外処理ではありませんが、それはまた少し間違っています。あなたの例外にメッセージがない場合は、スタックトレースの直前に奇妙なnullが表示されます。それがない場合は、メッセージが二回(Logbackでテスト)が表示されます:

22:51:23.985 WARN [main][Foo] OMG! - this is the exception message 
java.lang.IllegalStateException: OMG! - this is the exception message 
    at Foo.bar(Foo.java:20) ~[test-classes/:na] 

を...時には、望ましくない、例外メッセージが非常に長い場合は特に。


UPDATE:書くときに、独自の例外ロガーはorg.springframework.web.servlet.HandlerExceptionResolverorg.springframework.core.Orderedの両方を実装することを検討。 getOrder()は、ハンドラが組み込みのハンドラより優先されるように小さなもの(0など)を返す必要があります。

私のハンドラより前に実行していたorg.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolverが例外をログに記録せずにHTTP 500を返したことが起こりました。

+0

ありがとうございます。これは素晴らしい! – Peachy

関連する問題