如何让JSF页面先加载内容,后台Bean加载服务器状态后刷新数据表?
可行方案:异步加载状态+局部刷新数据表
针对你的需求,不用lazy加载,直接用异步线程处理状态获取+PrimeFaces局部刷新组件就能实现,以下是具体步骤:
1. 后台Bean处理逻辑
在托管Bean里初始化服务器列表(硬编码名称),给每个服务器设置初始状态为"加载中",再启动异步线程逐个获取真实状态,完成后更新服务器对象的状态:
import javax.annotation.PostConstruct; import javax.faces.view.ViewScoped; import javax.inject.Named; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @Named @ViewScoped public class ServerBean implements Serializable { private List<Server> servers; private boolean allStatusLoaded = false; @PostConstruct public void init() { // 初始化服务器列表,硬编码名称,状态设为加载中 servers = new ArrayList<>(); servers.add(new Server("服务器1", "loading")); servers.add(new Server("服务器2", "loading")); // 补充剩余8台服务器... // 启动异步线程获取状态 ExecutorService executor = Executors.newSingleThreadExecutor(); executor.submit(() -> { try { for (Server server : servers) { // 替换为你真实的耗时状态检查逻辑 Thread.sleep(1000); // 模拟单台服务器检查耗时1秒,总耗时10秒 String realStatus = checkServerStatus(server.getName()); server.setStatus(realStatus); } allStatusLoaded = true; } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { executor.shutdown(); } }); } // 模拟服务器状态检查方法 private String checkServerStatus(String serverName) { // 实际业务:调用接口/执行检查,返回"online"或"offline"等状态 return "online"; } // getter和setter public List<Server> getServers() { return servers; } public boolean isAllStatusLoaded() { return allStatusLoaded; } } // 服务器实体类 class Server implements Serializable { private String name; private String status; public Server(String name, String status) { this.name = name; this.status = status; } // getter和setter public String getName() { return name; } public void setName(String name) { this.name = name; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } }
2. 页面实现
用<p:dataTable>展示数据,状态列根据当前状态显示加载图标或真实状态图片;用<p:poll>定期检查状态加载进度,完成后停止轮询并刷新数据表:
<h:form> <p:dataTable id="serverTable" value="#{serverBean.servers}" var="server"> <p:column headerText="服务器名称"> <p:outputLabel value="#{server.name}" /> </p:column> <p:column headerText="服务器状态"> <!-- 加载中显示加载图标,状态完成后显示对应图片 --> <p:graphicImage name="images/loading.gif" rendered="#{server.status == 'loading'}" /> <p:graphicImage name="images/online.png" rendered="#{server.status == 'online'}" /> <p:graphicImage name="images/offline.png" rendered="#{server.status == 'offline'}" /> </p:column> </p:dataTable> <!-- 每2秒检查一次状态,刷新数据表,全部加载完成后停止轮询 --> <p:poll id="statusPoll" interval="2" update="serverTable" stop="#{serverBean.allStatusLoaded}" /> </h:form>
3. 补充说明
- 若不想用轮询,可改用PrimeFaces的
p:socket推送功能:后台状态全部获取完成后主动推送消息到前端,触发数据表刷新,这种方式更高效,但配置稍复杂。 - 异步线程用
ExecutorService管理,避免手动创建线程的资源问题;Bean使用@ViewScoped保证页面生命周期内数据一致性。 - 加载图标和状态图片请替换为你项目中的实际资源路径。
内容的提问来源于stack exchange,提问作者Raymond Kelly
相关产品推荐
相关产品推荐

