0

私が達成しようとしているのは、Raygun (クラッシュ報告サービス) を使用して、問題を経験したユーザーの詳細を送信することです。

私はもともと、これに似た方法を使用してユーザー名を取得しようとしました:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
username = authentication.getName();

しかし、何らかの理由で、これは値 を返しましたipaduser。その値がどこから来たのかはわかりませんが、これは明らかに答えではありません。

次に試しました:

System.getProperty("user.name");

ただし、これは、アプリケーションを使用しているユーザーのユーザー名ではなく、API サーバーにログインしているユーザーの名前を取得するだけです。

いろいろ調べてみたところ、ユーザーのデータベースのユーザー名と名前が、ApiAccessToken というカスタム オブジェクトに格納されていることがわかりました。問題は、この ApiAccessToken オブジェクトが Controller クラスのメソッドでのみ設定されていることです。

例えば:

@RequestMapping(path = "/api/foo", method = RequestMethod.GET)
public List<Bar> getBarForDatabase(@RequestParam(value = "api_key") String apiKey{
    ApiAccessToken accessToken = validateApiKey(apiKeyService, apiKey);
    // Etc
}

ApiAccessToken と validateApiKey() のコードは次のとおりです。

public final class ApiAccessToken {

    private String databaseName;
    private String username;

    public String getDatabaseName() { return databaseName; }

    public void setDatabaseName(String databaseName) { this.databaseName = databaseName; }

    public String getUsername() { return username; }

    public void setUsername(String username) { this.username = username; }
}

protected ApiAccessToken validateApiKey(ApiKeyService apiKeyService, String apiKey){
    UserAccountJdbcRepository userAccountJdbcRepository = new UserAccountJdbcRepository(createDataSourceForDatabase(USERS_DATABASE_NAME));
    ApiAccessToken accessToken = apiKeyService.validateApiKey(userAccountJdbcRepository, apiKey);
    if (accessToken == null) {
        throw new InvalidApiKeyException();
    }
    return  accessToken;
}

私のもう 1 つのアイデアは、値を格納する Controller クラスにローカル変数をapiKey用意し、getter を使用してその値を他のメソッドに渡すことでした。たとえば、Controller クラスでは次のようになります。

private static String apiKey;

public static String getApiKey() { return apiKey; }

@RequestMapping(path = "/api/foo", method = RequestMethod.GET)
public List<Bar> getBarForDatabase(@RequestParam(value = "api_key") String apiKey{
    ApiAccessToken accessToken = validateApiKey(apiKeyService, apiKey);
    apiKey = this.apiKey; 
    //Etc
}

次に、Raygun に例外の詳細を送信するクラスで:

 String apiKey = Controller.getApiKey();
 ApiAccessToken accessToken = validateApiKey(apiKeyService, apiKey);
 username = accessToken.getUsername();
 database = accessToken.getDatabaseName();

しかし、これは NullPointerException を返すだけで、Raygun には何も送信しません。

他に何を試すべきか完全にはわからないので、どんな助けでも大歓迎です。含めるべきだと思われるもので、私が省略したものがある場合はお知らせください。繰り返しますが、私はまだ Spring MVC にかなり慣れていないため、これのほとんどを書いた開発者はもう私たちと一緒に雇われていません。

4

2 に答える 2

1

api_key はリクエスト パラメータであるため、取得できる唯一の方法はコントローラーを介することです。

class Controller {

    @RequestMapping(path = "/api/foo", method = RequestMethod.GET)
    public List<Bar> getBarForDatabase(@RequestParam(value = "api_key") String apiKey) {
        ...

        Raygun.sendException(apiKey)
        ...
    }
}

class Raygun {
     public static sendException(String apiKey) {
         ApiAccessToken accessToken = validateApiKey(apiKeyService, apiKey);
         username = accessToken.getUsername();
         database = accessToken.getDatabaseName();
         ...
     }
}

複数の場所でAPIキーを使用してユーザー情報を取得したい場合は、インターセプターをご覧ください

于 2016-12-01T15:41:08.747 に答える
0

Minh Hoang からの提案により、この問題を解決することができました。

RaygunUnhandledExceptionHandler クラスにグローバル変数を追加しました。

private static ApiAccessToken accessToken = new ApiAccessToken();

次に、RaygunUnhandledExceptionHandler にこのメソッドを記述して、accessToken上記で宣言した変数を取得して設定します。

public static void getAccessTokenFromController(ApiAccessToken accessTokenFromController) { accessToken = accessTokenFromController; }

次に、次の行をコントローラーの /api/foo に追加して、accesstokenRaygunUnhandledExceptionHandlerに送信するようにしました。

// Sends the API Key to RaygunUnhandledExceptionHandler
RaygunUnhandledExceptionHandler.getAccessTokenFromController(accessToken);

そして、RaygunUnhandledExceptionHandler の defaultErrorHandler() で:

ArrayList tags = new ArrayList<String>();
tags.add("username: " + accessToken.getUsername());
tags.add("database: " + accessToken.getDatabaseName());


これを整理するのを手伝ってくれた Minh Hoang と fantaghirocco に再び感謝します。

この実装に問題がある場合はお知らせください。

于 2016-12-02T00:45:34.210 に答える