我有一个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()));
非常感谢您的帮助!
答案 0 :(得分:2)
从服务器检索数据是或者至少有可能是长期运行的操作。您不应该在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's excellent article。