Java 调用具有返回类型和要调用的方法的方法

Java Call method with return type and method to be called

提问人:jalmen 提问时间:10/26/2022 更新时间:10/27/2022 访问量:366

问:

我有很多针对 REST API 的调用,我希望以相同的方式处理这些调用。 执行呼叫,检查是否未通过身份验证。再次刷新令牌调用,或者如果我们达到速率 尽管速率限制功能,但限制。睡眠并再次执行通话。

我想把它包装在一个可以调用的函数中

 ReturnType returnVal=  handleIntegration(ReturnType , functionToBecCalled)

如何实现这一目标?

对于下面的示例,例如

CustomersResponse customersReponse = handleIntegration(CustomersResponse , connection.customers.findCustomersResponse())
EmployeesReponse employeesRepsonse = handleIntegration(EmployeeResponse , connection.employees.findEmployeesResponse())

当前代码

            bucket.consume();
            CustomersResponse customersResponse = null;
            try {
                 customersResponse = connection.customers.findCustomersResponse();
            } catch (IntegrationException e) {
                if (e.getStatusCode() == 401) {
                    this.newAccessFromRefreshToken();
                    customersResponse = connection.customers.findCustomersResponse();
                }else if (e.getStatusCode() == 429){
                    Thread.sleep(500);
                    customersResponse = connection.customers.findCustomersResponse();
                }else
                    throw e;
            }   

        bucket.consume();
            EmployeeResponse employeeResponse = null;
            try {
                 employeeResponse = connection.employees.findEmployeesResponse();
            } catch (IntegrationException e) {
                if (e.getStatusCode() == 401) {
                    this.newAccessFromRefreshToken();
                    employeeResponse = connection.employees.findEmployeesResponse();
                }else if (e.getStatusCode() == 429){
                    Thread.sleep(500);
                    employeeResponse = connection.employees.findEmployeesResponse();
                }else
                    throw e;
            }   
Java 方法 调用

评论

0赞 Godwin 10/26/2022
bucket.consume();这是否意味着您已经在项目中使用了某种队列机制?
0赞 jalmen 10/26/2022
是的,这仅适用于速率限制器。它将检查是否不经常拨打电话。但是我们已经看到,我们调用的 API 并不稳定,有时可能会给出 429,尽管没有超过速率限制。但这只是一个旁注,对于我想通过问题实现的功能并不重要

答:

1赞 Nikos Paraskevopoulos 10/26/2022 #1

如果您至少在 Java 8 上使用 lambdas,您可以这样做:

<T> T handleIntegration(Supplier<T> method) {
  bucket.consume(); // I don't know how this fits - BEWARE!
  T response = null;
  try {
    response = method.get();
  } catch (IntegrationException e) {
    if (e.getStatusCode() == 401) {
      this.newAccessFromRefreshToken();
      response = method.get();
    } else if (e.getStatusCode() == 429){
      Thread.sleep(500);
      response = method.get();
    } else
      throw e;
    }
  }
  // I don't know what you want to do with the response, returning it here for example
  return response;
}

并使用它,例如:

CustomersResponse customersReponse = handleIntegration(
  CustomersResponse.class,
  () -> connection.customers.findCustomersResponse()
);

警告:我认为这是一个未经检查的异常。如果它被检查或在任何情况下,例如 抛出一个选中的异常,提供的将不做。您必须提供一个功能接口,该接口会引发特定的已检查异常。IntegrationExceptionconnection.customers.findCustomersResponse()java.util.function.Supplier

不相关 注意:很容易,但你可能要考虑一个更好的方法,因为阻塞了线程。Thread.sleep()sleep

评论

0赞 jalmen 10/26/2022
是的,需要以某种方式处理 IntegrationException。它不是由 method.get() 抛出的
2赞 mrkachariker 10/26/2022 #2

在 Java 8+ 函数接口和泛型的帮助下,您可以尝试如下操作:

public <T> T handleIntegration(Supplier<T> supplier) {
    bucket.consume();
    T result = null;
    try {
        result = supplier.get();
    } catch (IntegrationException e) {
        if (e.getStatusCode() == 401) {
            this.newAccessFromRefreshToken();
            result = supplier.get();
        } else if (e.getStatusCode() == 429) {
            Thread.sleep(500);
            result = supplier.get();
        } else
            throw e;
    }
    return result;
}

然后,您可以像这样调用该方法:

CustomersResponse returnVal = handleIntegration(connection.customers::findCustomersResponse)