从其他类中的方法中获取参数值



我要实现的目标是,使用Raygun(崩溃报告服务),向经历过该问题的用户的用户详细信息发送。

我最初尝试使用类似的方法获取用户名:

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

,但由于某种原因,这返回了该值ipaduser。我不确定该价值来自哪里,但这显然不是答案。

我尝试了:

System.getProperty("user.name");

但这只是获取我们API服务器登录的用户的名称,而不是使用应用程序的用户的用户名。

四处挖掘后,我发现用户的用户名和名称存储在称为apiaccesstoken的自定义对象中。问题是,此apiaccesstoken对象仅在我们的控制器类中的方法中设置。

例如:

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

apiaccesstoken和dialateapikey()的代码如下:

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;
}

我的另一个想法是在控制器类中拥有一个局部变量,该变量将存储apiKey的值,然后我将该值传递给使用Getter的其他方法。例如,在控制器类中:

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,而不会发送任何东西。

任何帮助都将不胜感激,因为我不确定还要尝试什么。让我知道我认为我应该包括的东西是否有什么。再一次,我仍然是Spring MVC的新手,而写作大部分的开发人员不再与我们一起使用。

作为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键获取用户信息,请查看Interceptor

带有Minh Hoang的建议,我能够解决此问题。

我为RaygununhandledExceptionHandler类添加了一个全局变量:

private static ApiAccessToken accessToken = new ApiAccessToken();
然后,我在RaygunhandledExceptionHandler中写下此方法以获取accessToken并将其设置为我在上面声明的变量:
public static void getAccessTokenFromController(ApiAccessToken accessTokenFromController) { accessToken = accessTokenFromController; }

i然后将此行添加到控制器中的/api/foo,以便将accesstoken发送到RaygunhandledExceptionHandler:

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

,然后在raygunhandledexceptionhandler中的defaulterrorhandler()中:

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


再次感谢Minh Hoang和Fantaghirocco帮助我解决这个问题。

如果您看到此实现的任何问题,请告诉我。

最新更新