My .onSucceed(okhttp)抛出“只能从FX应用程序线程使用服务”

问题描述 投票:0回答:2

我编写了一个拦截器,该拦截器捕获401 HTTP状态,然后调用一种方法,该方法将RefreshToken发送到服务器以获取新的AccessToken。出于某种原因,它不起作用,尽管在同一个类中,我得到了第二个函数,该函数几乎相同并且可以完全正常工作。

我错过了什么吗?预先感谢。

发生错误的功能:

public void RefreshToken(){
    try{
      if(db==null){
        db=Database.newInstance();
      }
    }catch(Exception ex){
      System.out.println("Error in while getting new Database");
    }
    Service<String> t=db.GetAccessToken();


    t.setOnSucceeded(e -> { //Error thrown here
      Database.ACCESSTOKEN=t.getValue();
    });
    t.setOnFailed(e -> {
      System.out.println("Error with HTTP GET new Token");
    });
  }

几乎相同的功能:

private void Login(String username, String password) {
    Service<BothTokens> t=db.Login(new Credentials(username,password));
    t.setOnSucceeded(e -> {
      Database.REFRESHTOKEN=t.getValue().getRefreshToken();
      Database.ACCESSTOKEN=t.getValue().getAccessToken();
      openMainFXML();
      closeWindow();
    });
    t.setOnFailed(e -> {
      new ServiceExceptionHandler<>(t).handleServiceWithRetryOrClose((Stage) btnLogin.getScene().getWindow(),
          "Error beim Login",
          t.getException().getMessage(), (Exception) t.getException());
    });
  }

拦截器:

OkHttpClient OK_HTTP_CLIENT = new OkHttpClient.Builder().addInterceptor(chain -> {
        Response originalResponse = chain.proceed(chain.request());
        if(originalResponse.code()==401){
            try{
                Login_Controller login=Login_Controller.newInstance();
                login.RefreshToken();
            }catch(Exception ex){
                System.out.println("Error getting new Token");
                ex.printStackTrace();
            }
        }
        return originalResponse;
    }).build();

例外:

java.lang.IllegalStateException: Service must only be used from the FX Application Thread
  at javafx.concurrent.Service.checkThread(Service.java:906)
  at javafx.concurrent.Service.setOnSucceeded(Service.java:409)
  at pkgController.Login_Controller.RefreshToken(Login_Controller.java:106)
  at pkgServices.statics.StaticServerObjects.lambda$static$0(StaticServerObjects.java:19)
  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
  at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.kt:184)
  at okhttp3.RealCall.execute(RealCall.kt:66)
  at pkgServices.buildings.GetBuildings$1.call(GetBuildings.java:32)
  at pkgServices.buildings.GetBuildings$1.call(GetBuildings.java:25)
  at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  at javafx.concurrent.Service.lambda$null$493(Service.java:725)
  at java.security.AccessController.doPrivileged(Native Method)
  at javafx.concurrent.Service.lambda$executeTask$494(Service.java:724)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
  at java.lang.Thread.run(Thread.java:748)
java.lang.Exception: java.lang.Exception: Exception occured in GetBuildings with code: 401
  at pkgServices.buildings.GetBuildings$1.call(GetBuildings.java:40)
  at pkgServices.buildings.GetBuildings$1.call(GetBuildings.java:25)
  at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  at javafx.concurrent.Service.lambda$null$493(Service.java:725)
  at java.security.AccessController.doPrivileged(Native Method)
  at javafx.concurrent.Service.lambda$executeTask$494(Service.java:724)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
  at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.Exception: Exception occured in GetBuildings with code: 401
  at pkgServices.buildings.GetBuildings$1.call(GetBuildings.java:37)
  ... 9 more
java http exception javafx okhttp
2个回答
0
投票

问题是该函数在与FXML-Controller不同的线程中运行,我不得不编写

Platform.runLater(() -> {....} )

0
投票

我建议使用javafx AsyncTaskLibray并准备您的请求,如下所示:

公共类示例扩展了AsyncTask {私有的UIController控制器;

public Example(UIController controller) {
    this.controller = controller;
}

@Override
void onPreExecute() {
    //PREPARE GUI, SHOW PROGRESS OR SOMETHING....
    this.controller.updateProgressLabel("Starting Download")
}

@Override
String doInBackground() {
    //THIS METHOD WORKING IN BACKGROUND HERE YOU SOULD IMPLEMENT CODE OF HTTP REQUEST AND RETURN RESULT OF REQUEST FOR EXAMPLE OBJECT OR JSON STRING
  return new String();
}

@Override
void onPostExecute(String result) {
    //HERE YOU CAN GET YOUR DATA FROM REQUEST AND SET RESULT ON GUI
    this.controller.updateProgressLabel("result);
}

@Override
void progressCallback(Object... params) {

}

}

© www.soinside.com 2019 - 2024. All rights reserved.