5

例外に応じて catch ブロックに異なるコードを自動的に生成する方法があるかどうかは誰にもわかりませんか?

Eclipse 関数 'Surround with try/catch' は、スタック トレースのダンプのみを含む try/catch ブロックを生成します。

私はコードで似たようなことをたくさんしているので、私の例外のほとんどはおそらく 3 つほどの異なるタイプに要約されます。それぞれに異なる catch ブロック コードを使用し、例外に基づいて Eclipse の自動フォーマットを使用したいと考えています。

例: 私のコードが RemoteConnectionException を生成した場合、ユーザーに再接続するためのダイアログを表示したいと思います。RemoteContentException が生成された場合は、ログに記録したいと思います。

(私はこれらを作りました。)

前もって感謝します

更新: 私はいろいろ調べていて、2 つの潜在的な解決策があります。

1) 高速コード プラグインと呼ばれる、探している機能を実行できるものを見つけました。 http://fast-code.sourceforge.net/index.htm

2) 例外を具体的に処理するには、おそらく一般的な例外ハンドラーを作成し、catch ブロック コードを変更して、スタック トレースを出力する代わりに例外を渡すようにします。次に、Java コードは、例外の種類に基づいて実行するアクションを決定します。

4

2 に答える 2

4

テンプレートには限界があります。ただし、Aspect を使用すると、問題を非常にエレガントに解決できます。( http://www.eclipse.org/aspectj/ )必要なすべてのタイプの「テンプレートケース」に対して新しい注釈を作成し、アドバイスを回避するだけです。

Ps: printStackTrace() を syserr/sysout に使用しないでください。非常に多くの製品グレードの軽量ロギング フレームワークがあります....お願いします...かわいそうな小さな System.out/err を悪用しないでください :)

編集:

ロギング/ベンチマークのアドバイスの例。(注:アスペクトにはSpring AOPを使用し、ロギングフレームワークに簡単にアクセスするにはlombokを使用しています。getCurrentUser()コードはここではあまり関係ありません。Spring Securityから現在のユーザーを取得するためだけです)

package com.XXXXXXXX.aspects;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

@Component
@Aspect
@Slf4j
public class LoggerAspect {

    private final static String DOMAIN = "XXXXXXXX";

    private static String getCurrentUser() {
        String username = "Unknown";
        try {
            Object principal = SecurityContextHolder.getContext().
                    getAuthentication().
                    getPrincipal();
            if (principal instanceof UserDetails) {
                username = ((UserDetails) principal).getUsername();
            } else {
                username = principal.toString();
            }
        } catch (Exception e) {
        }
        return username;
    }

    @Pointcut("within(com.XXXXXXXX.services..*)")
    public void inServiceLayer() {
    }

    @Pointcut("execution(* getMatcherInfo(..)) || execution(* resetCounter(..))")
    public void notToAdvise() {
    }

    @Around("com.XXXXXXXX.aspects.LoggerAspect.inServiceLayer() && !com.XXXXXXXX.aspects.LoggerAspect.notToAdvise()")
    public Object doLogging(ProceedingJoinPoint pjp)
            throws Throwable {
        long start = System.nanoTime();
        StringBuilder sb = new StringBuilder(DOMAIN);
        sb.append('/').
                append(getCurrentUser()).
                append(" accessing ").
                append(pjp.getSignature().
                getDeclaringTypeName()).
                append('.').
                append(pjp.getSignature().
                getName());
        log.trace("START: " + sb.toString());
        Object retVal = pjp.proceed(pjp.getArgs());
        long duration = System.nanoTime() - start;
        log.trace("STOP: " + duration / 1000000 + " msec. " + sb.toString());
        return retVal;
    }
}
于 2012-07-02T22:44:48.247 に答える
0

日食で利用可能なそのようなオプションがあるかどうかはわかりません。私はかなり前から try/catch オプションでサラウンドを使用してきましたが、例外 e の catch ブロックに常にデフォルトの e.printStackTrace() 行をダンプします。

于 2012-07-02T22:29:31.350 に答える