当前位置: 首页 > 知识库问答 >
问题:

如何从泽西REST API方法返回响应,该方法内部有列表器

秦天宇
2023-03-14

我正在尝试创建REST api,以使用Firebase Server SDK和Jersey执行写入操作。

以下是我要做的:

  1. 初始化Firebase SDK
  2. 从客户端获取idToken并验证idToken
  3. 在少数Firebase节点上执行一些写入操作
  4. 发送api响应

我只想在Firebase写入操作成功或失败时返回Response。这发生在Firebase Listeners内部。然而,我尝试从侦听器返回值,但由于Firebase侦听器具有void返回类型,所以收到错误消息。

我如何从监听器返回响应?

这是我的代码。

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

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

共有2个答案

苍恩
2023-03-14

我回答这个问题可能有点晚,但在试用Firebase服务器SDK后,我发现您可以在SDK中创建一个可用的任务以同步等待响应。下面的片段可能会对您有所帮助:

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();
    }
}
皇甫通
2023-03-14

所以我猜测Firebase SDK本质上是异步的。在这种情况下,如果您使用的是Jersey 2.x,则可以使用异步服务器支持。您只需调用AsyncResponse。恢复(响应)。例如

@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());
        }
    });
}

如果你使用的是Jersey 1.x,实际上没有异步选项。您只需要用< code>CountDownLatch阻塞流,在回调中分配一个本地< code>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;
}
 类似资料:
  • 我有一个CustomRequest类: } 然后我有我的类JSONRequest: } 我想做的是在我的postRequest方法中,有一个CustomRequest类的对象叫做JSONObject Request,我想将JSONObject响应变量从onResponse方法返回给父postRequest方法,我在以下位置得到一个错误: 因为它告诉我方法的返回类型是void,请告诉我我做错了什么,

  • 问题内容: 我有一个私有方法,该方法接受一个整数值列表,并返回一个整数值列表。我如何使用电源模拟进行测试。我是powermock的新手。我可以通过简单的模拟进行测试吗?怎么样.. 问题答案: 从该文件中,部分被称为“公共- 旁路封装”: 使用Whitebox.invokeMethod(..)调用实例或类的私有方法。 您也可以在同一部分中找到示例。

  • 问题内容: 我想做这样的事情: 不幸的是,列表追加未返回修改后的列表。 那么,我如何允许返回新列表? 问题答案: 不要使用追加而是串联: 这将返回一个 新 列表。不会受到影响。如果你需要有受影响的 还有 既可以使用,无论如何,然后分配分开(复印件)。

  • 我试图编写一个方法,它接受@PathVariable参数,并将用户重定向到一个jsp文件。 @pathvariable(value=“customerId”)字符串customerId @pathvariable(name=“customerId”)字符串customerId @pathvariable(“customerId”)字符串customerId 谢谢你的帮助。

  • 我想返回与我在中获得的参数具有相同对象的相同列表。如果我得到

  • 关于方法何时应该返回CompletableFuture的一般准则是什么?假设有两个类A和B,其中类B有一个执行大量IO的方法performTask(),类A调用performTask()方法在Java可以使用以下方法编写多线程代码: < li >让方法的调用方决定是否使用ThreadPool异步执行方法。在这种情况下,A将异步调用performTask()方法,这样类B就不需要使其方法异步。 <