我编写了一个拦截器,该拦截器捕获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
问题是该函数在与FXML-Controller不同的线程中运行,我不得不编写
Platform.runLater(() -> {....} )
我建议使用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) {
}
}