我有一个JavaFX应用程序,它通过Jersey客户端API使用Web服务,每隔一段时间,应用程序(屏幕)的一部分在执行对Web服务的调用时冻结。
我没有用于进行 Web 服务调用的线程。
以下是泽西岛客户端代码:
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.json.JSONConfiguration;
public class WSClient{
WebResource webResource;
ClientResponse response;
protected Client getWSClient() {
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(
JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
Client wsClient = Client.create(clientConfig);
return wsClient;
}
public ArrayList<String> getNames(){
ArrayList<String> names= new ArrayList<>();
try{
webResource = getWSClient().resource("http://localhost:8080/names");
response = webResource.type("application/json").accept("application/json").get(ClientResponse.class);
}catch(Exception ex){
log.error("Failed : " + ex.getMessage());
return null;
}
if(response.getStatus() != 200){
return null;
}
String output = response.getEntity(String.class);
names= getGson().fromJson(output,
new TypeToken<ArrayList<String>>() {
}.getType());
return names;
}
}
以下是 JavaFX 控制器类:
private ComboBox<String> cmbNames = new ComboBox<>();
cmbNames.setItems(FXCollections.observableList(new WSClient().getNames()));
非常感谢您的帮助!
从服务器检索数据是,或者至少有可能是一个长时间运行的操作。不应在 FX 应用程序线程上执行此类操作,因为在操作过程中 UI 将无响应。
创建一个Task
来执行该操作,并在后台线程中执行它:
Task<List<String>> getNamesTask = new Task<List<String>>() {
@Override
public List<String> call() {
return new WSClient().getNames();
}
};
getNamesTask.setOnSucceeded(e ->
cmbNames.getItems().setAll(getNamesTask.getValue()));
要在后台线程中执行任务,您可以"手动"执行此操作:
Thread thread = new Thread(getNamesTask);
thread.setDaemon(true);
thread.start();
或者(更好),使用将为您管理线程池的Executor
:
// declared at class level:
private final Executor exec = Executors.newCachedThreadPool(runnable -> {
Thread t = new Thread(runnable);
t.setDaemon(true);
return t ;
});
// ...
exec.execute(getNamesTask);
有关将客户端-服务器通信与JavaFX集成的更多策略,请查看Adam Bien的优秀文章。