简体   繁体   English

如何从Jersey REST api方法返回Respone,其中包含列表器

[英]How to return Respone from Jersey REST api method which has listners inside

I am trying to create REST apis to perform write operations using Firebase Server SDK and Jersey. 我正在尝试创建REST apis以使用Firebase Server SDK和Jersey执行写入操作。

Here is what I am trying to do: 这是我想要做的:

  1. Initializing Firebase SDK 初始化Firebase SDK
  2. Getting idToken from Client and Validating idToken 从客户端获取idToken并验证idToken
  3. Performing some write operations on few Firebase nodes 在少数Firebase节点上执行一些写操作
  4. Sending api Response 发送api响应

I want to return Response only if Firebase write operation succeeds or fails. 我想仅在Firebase写入操作成功或失败时返回Response。 That happens inside of Firebase Listeners. 这发生在Firebase监听器内部。 However, I try to return value from Listeners, I get error becuase Firebase listeners have void return type. 但是,我尝试从Listeners返回值,我得到错误,因为Firebase侦听器具有void返回类型。

How can I return response from the listener? 我怎样才能从听众那里回复?

Here is my code. 这是我的代码。

MyEndpoint.java MyEndpoint.java

@Path("/restapi")
//BaseEndpoint does Authentication operations
public class MyEndpoint extends BaseEndpoint {

    public void Authenticate(String token, AuthenticationListener authenticationResultListener) {
        super.Authenticate(token, authenticationResultListener);
    }

    @POST
    @Produces("application/json")
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public Response createCommunity(@FormParam("idToken") String idToken) {
        Authenticate(idToken, new AuthenticationListener() {
            @Override
            public void onAuthenticationSuccess() {
                // The app only has access as defined in the Security Rules
                DatabaseReference ref = FirebaseDatabase.getInstance().getReference("/mysamplenode");
                ref.addListenerForSingleValueEvent(new ValueEventListener() {
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        String res = dataSnapshot.getKey();
                        //I will do some write operations on Firebase here
                        //If they complete successfuly only then I want to return api response
                        return Response.status(200).entity().build();
                    }
                    @Override
                    public void onCancelled(DatabaseError arg0) {
                        System.out.println("DatabaseError-------------" + arg0);
                        return Response.status(500).entity("DatabaseError").build();
                    }
                });
            }
            @Override
            public void onAuthenticationFailure() {
                return Response.status(403).entity("Forbidden").build();
            }
        });
    }
}

BaseEndpoint.java BaseEndpoint.java

    public class BaseEndpoint {

    public static String uid;

    public void Authenticate(String token, AuthenticationListener authenticationResultListener) {
        // idToken comes from the client app
        FirebaseAuth.getInstance().verifyIdToken(token).addOnFailureListener(new OnFailureListener() {

            @Override
            public void onFailure(Exception arg0) {
                System.out.println("Uid exp= " + arg0);
                authenticationResultListener.onAuthenticationFailure();
            }
        }).addOnSuccessListener(new OnSuccessListener<FirebaseToken>() {
            @Override
            public void onSuccess(FirebaseToken decodedToken) {
                uid = decodedToken.getUid();
                System.out.println("Uid= " + uid);
                authenticationResultListener.onAuthenticationSuccess();
            }
        });
    }
}

So I'm guessing the Firebase SDK is asynchronous in nature. 所以我猜测Firebase SDK本质上​​是异步的。 In which case, if you're using Jersey 2.x, you can use the asynchronous server support . 在这种情况下,如果您使用的是Jersey 2.x,则可以使用异步服务器支持 You can just call AsyncResponse.resume(Response) in your callbacks. 您可以在回调中调用AsyncResponse.resume(Response) For example 例如

@POST
@Produces("application/json")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public void createCommunity(@FormParam("idToken") String idToken,
                                @Suspended final AsyncResponse response) {
    Authenticate(idToken, new AuthenticationListener() {
        @Override
        public void onAuthenticationSuccess() {
            DatabaseReference ref = FirebaseDatabase.getInstance()
                    .getReference("/mysamplenode");
            ref.addListenerForSingleValueEvent(new ValueEventListener() {
                public void onDataChange(DataSnapshot dataSnapshot) {
                    String res = dataSnapshot.getKey();                        
                    response.resume(Response.status(200).entity().build());
                }
                @Override
                public void onCancelled(DatabaseError arg0) {
                    response.resume(Response.status(500).entity("DatabaseError").build());
                }
            });
        }
        @Override
        public void onAuthenticationFailure() {
            response.resume(Response.status(403).entity("Forbidden").build());
        }
    });
}

If you're using Jersey 1.x, there's not really an async option. 如果您使用的是Jersey 1.x,那么实际上并不存在异步选项。 You just need to block flow with a CountDownLatch , assign a local Response in the callbacks, and count down. 您只需要使用CountDownLatch阻止流,在回调中分配本地Response ,然后倒计时。

@POST
@Produces("application/json")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public void createCommunity(@FormParam("idToken") String idToken) {
    Response response;
    CountDownLatch latch = new CountDownLatch(1);
    Authenticate(idToken, new AuthenticationListener() {
        @Override
        public void onAuthenticationSuccess() {
            DatabaseReference ref = FirebaseDatabase.getInstance()
                    .getReference("/mysamplenode");
            ref.addListenerForSingleValueEvent(new ValueEventListener() {
                public void onDataChange(DataSnapshot dataSnapshot) {
                    String res = dataSnapshot.getKey();                        
                    response = Response.status(200).entity().build();
                    latch.countDown();
                }
                @Override
                public void onCancelled(DatabaseError arg0) {
                    response = Response.status(500).entity("DatabaseError").build();
                    latch.countDown();
                }
            });
        }
        @Override
        public void onAuthenticationFailure() {
            response = Response.status(403).entity("Forbidden").build();
            latch.countDown();
        }
    });
    latch.await();
    return response;
}

I might be a little late in answering this question, but after trying the Firebase server SDK out I found that you can create a Task available in the SDK to wait for a response synchronously. 我可能在回答这个问题时有点迟,但在尝试使用Firebase服务器SDK后,我发现您可以在SDK中创建一个可用于同步等待响应的任务。 The snippet below might help you out: 下面的代码段可能会帮到你:

public class BaseEndpoint {

    public static String uid;

    public void Authenticate(String token, AuthenticationListener authenticationResultListener) {
        // idToken comes from the client app
        FirebaseToken firebaseToken = null;
        try {
            Task<FirebaseToken> authTask = FirebaseAuth.getInstance().verifyIdToken(token);
            Tasks.await(authTask);
            firebaseToken = authTask.getResult();
        } catch (Exception e) {
            authenticationResultListener.onAuthenticationFailure();
        }
        uid = firebaseToken.getUid();
        System.out.println("Uid= " + uid);
        authenticationResultListener.onAuthenticationSuccess();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将PNG图像从Jersey REST服务方法返回到浏览器 - How to return a PNG image from Jersey REST service method to the browser 如何在Jersey REST API中返回部分实体/ POJO - How to return partial entities/POJOs in Jersey REST api java应用程序中的方法。该方法应从Rest Api返回数据 - A method in java application .Which method should return data from Rest Api Jersey 2.26 REST API-Json返回无法正常工作 - Jersey 2.26 REST API - Json return not working 球衣休息:如何返回接口而不是上课 - jersey rest: how to return interface instead of class Jersey REST:如何编写包括验证HTTP授权的Jersey方法 - Jersey REST:How to write a jersey method including verifying HTTP Authorization CRUD在休眠状态下从ManyToMany中使用Jersey使用Java的REST API在REST API中使用POST方法读取JSON的问题 - CRUD issue reading a JSON using POST method in a REST API in Java using Jersey from a ManyToMany noted in hibernate 如何实现接收一个或多个字符串并返回字符串的rest jersey方法 - How implement rest jersey method that receives one or more String and return a String 如何使用Jersey调用Google Drive REST API? - How to invoke Google Drive REST API with Jersey? 如何在过滤器其余部分中获取Cookie - How to get cookie in filter rest api jersey
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM