Java Spring - 从异步回调返回?

Dav*_*ris 4 java spring asynchronous firebase firebase-authentication

使用Spring(Java)和Firebase处理后端.我们使用Firebase令牌(附加为身份验证标头)来识别用户,使用内置的UID.

不幸的是,从令牌中提取此UID必须异步完成,因此我只能从onSuccess回调中获取令牌.要提供响应,我必须从下面的deleteUser方法返回一个对象,但是在得到成功/失败回调之前我无法知道响应是什么!

我可以想象一种方法,通过等待一个标志来设置我的回调,或者有一些凌乱的时间,但是我想知道是否有一种干净的方式来处理这个而不引入竞争条件或许多额外的代码.有人可以帮忙吗?

请求映射(处理请求,提供响应)

    @RequestMapping(value = "/users", method = RequestMethod.DELETE)
    public @ResponseBody String deleteUser(@RequestHeader("Authentication") String token) {
        FirebaseUtil.getUid(token, new OnSuccessListener<FirebaseToken>() {
            @Override
            public void onSuccess(FirebaseToken decodedToken) {
                String uid = decodedToken.getUid();
                //RETURN SUCCESSFUL HERE
            }
        }, new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                //RETURN FAILURE HERE
            }
        });

        //MUST RETURN SOMETHING HERE?
        User userToDelete = userDao.get(uid); //DONT HAVE THE uid HERE
        userDao.delete(uid);
        clearUserAccounts(userToDelete);
        return uid + " was deleted";
    }
Run Code Online (Sandbox Code Playgroud)

FirebaseUtil.getUid()

public static void getUid(String token, OnSuccessListener<FirebaseToken> successListener, OnFailureListener failureListener) {
        FirebaseAuth.getInstance()
                .verifyIdToken(token)
                .addOnSuccessListener(successListener)
                .addOnFailureListener(failureListener);
    }
Run Code Online (Sandbox Code Playgroud)

vzs*_*zsg 6

虽然在异步请求完成之前有一些方法可以阻塞线程,但是从Spring 3.2开始,有一个简单且资源有效的解决方案.

您可以使用DeferredResult<T>返回类型来启用异步处理.这允许servlet容器立即重用HTTP工作线程,同时避免强行序列化一系列异步请求.

通过填写注释,您的代码将如下所示:

@RequestMapping(value = "/users", method = RequestMethod.DELETE)
public DeferredResult<String> deleteUser(@RequestHeader("Authentication") String token) {
    final DeferredResult<String> result = new DeferredResult<>();

    FirebaseUtil.getUid(token, new OnSuccessListener<FirebaseToken>() {
        @Override
        public void onSuccess(FirebaseToken decodedToken) {
            String uid = decodedToken.getUid();
            User userToDelete = userDao.get(uid);
            userDao.delete(uid);
            clearUserAccounts(userToDelete);
            result.setResult(uid + " was deleted");
        }
    }, new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            result.setErrorResult(e);
        }
    });

    return result;
}
Run Code Online (Sandbox Code Playgroud)