You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JSF中展示JavaScript获取的JSON数组数据?

解决JSF页面加载时从Web API获取数据并展示到表格的问题

作为JSF新手,你已经成功拿到API数据了,这很棒!接下来只需要把数据和页面表格关联起来就行,这里给你两种可行的方案,你可以根据自己的需求选择:

方案一:纯前端JavaScript动态渲染表格(快速实现)

这种方法基于你已经写好的fetch代码,只需要在页面里加个表格容器,然后在拿到数据后动态生成表格行就可以了。

1. 修改页面结构,添加表格容器

在<h:body>里加入带表头的表格,留好tbody用来填充数据:

<h:body onload="calledOnLoad();">
  <table id="dataTable" border="1" cellpadding="8" cellspacing="0">
    <thead>
      <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Price</th>
        <th>URL</th>
        <th>Count</th>
      </tr>
    </thead>
    <tbody id="tableBody">
      <!-- 数据会在这里动态生成 -->
    </tbody>
  </table>
</h:body>

2. 更新JavaScript函数,渲染数据

修改你的calledOnLoad函数,在拿到API返回的data后,遍历数组生成表格行:

function calledOnLoad() { 
  const tableBody = document.getElementById("tableBody");
  // 先清空表格原有内容,避免重复加载
  tableBody.innerHTML = "";
  
  fetch("http://localhost:1234/api/mydata") 
  .then(response => {
    // 先检查请求是否成功
    if (!response.ok) throw new Error(`请求失败:${response.status}`);
    return response.json();
  })
  .then(data => { 
    console.log(data);
    // 遍历每个数据项,创建表格行
    data.forEach(item => {
      const row = document.createElement("tr");
      
      // 逐个创建单元格并赋值
      row.innerHTML = `
        <td>${item.ID}</td>
        <td>${item.Name}</td>
        <td>${item.Price}</td>
        <td>${item.URL}</td>
        <td>${item.Count}</td>
      `;
      
      tableBody.appendChild(row);
    });
  }) 
  .catch(error => { 
    console.log("获取数据出错:", error); 
  });
}

这样页面加载完成后,数据就会自动渲染到表格里了。

方案二:使用JSF托管Bean(推荐,符合JSF开发规范)

JSF是服务器端框架,更推荐在后端处理API请求,再通过JSF组件绑定数据,这样更利于后续维护和扩展。

1. 创建托管Bean处理API请求

新建一个Java类DataBean.java,负责调用API并存储数据:

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;

// 声明为托管Bean,作用域为当前视图
@ManagedBean(name = "dataBean")
@ViewScoped
public class DataBean {
    // 内部类映射API返回的数据结构
    public static class Item {
        private int ID;
        private String Name;
        private double Price;
        private String URL;
        private int Count;
        
        // 必须要有无参构造函数,JSF需要
        public Item() {}
        
        // getter和setter方法,JSF组件会用到
        public int getID() { return ID; }
        public void setID(int ID) { this.ID = ID; }
        public String getName() { return Name; }
        public void setName(String Name) { this.Name = Name; }
        public double getPrice() { return Price; }
        public void setPrice(double Price) { this.Price = Price; }
        public String getURL() { return URL; }
        public void setURL(String URL) { this.URL = URL; }
        public int getCount() { return Count; }
        public void setCount(int Count) { this.Count = Count; }
    }
    
    private List<Item> items;
    
    // Bean初始化时自动调用这个方法获取数据
    @PostConstruct
    public void init() {
        items = fetchDataFromAPI();
    }
    
    private List<Item> fetchDataFromAPI() {
        List<Item> itemList = new ArrayList<>();
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("http://localhost:1234/api/mydata"))
                .build();
        
        try {
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            if (response.statusCode() == 200) {
                // 用Jackson把JSON字符串转成对象列表
                ObjectMapper mapper = new ObjectMapper();
                itemList = mapper.readValue(response.body(), 
                    mapper.getTypeFactory().constructCollectionType(List.class, Item.class));
            } else {
                System.err.println("API请求失败,状态码:" + response.statusCode());
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        return itemList;
    }
    
    // 提供getter方法让JSF页面访问数据
    public List<Item> getItems() {
        return items;
    }
}

2. 修改JSF页面使用<h:dataTable>组件

去掉原来的onload函数,改用JSF的表格组件绑定Bean里的数据:

<!DOCTYPE html> 
<HTML lang="en" xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core"> 
<h:head> 
    <title>数据展示页面</title> 
    <style>
        table {border-collapse: collapse;}
        th, td {border:1px solid #ccc; padding:8px;}
        th {background-color:#f5f5f5;}
    </style>
</h:head> 
<h:body> 
    <h:dataTable value="#{dataBean.items}" var="item" styleClass="data-table">
        <!-- 定义每一列的表头和内容 -->
        <h:column>
            <f:facet name="header">ID</f:facet>
            #{item.ID}
        </h:column>
        <h:column>
            <f:facet name="header">Name</f:facet>
            #{item.name}
        </h:column>
        <h:column>
            <f:facet name="header">Price</f:facet>
            #{item.price}
        </h:column>
        <h:column>
            <f:facet name="header">URL</f:facet>
            #{item.URL}
        </h:column>
        <h:column>
            <f:facet name="header">Count</f:facet>
            #{item.count}
        </h:column>
    </h:dataTable>
</h:body> 
</HTML>

注意事项

  • 使用方案二需要添加Jackson依赖(用于JSON解析),如果是Maven项目,在pom.xml里加入:
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version>
</dependency>

内容的提问来源于stack exchange,提问作者Robert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 09:42:41