如何将对象列表插入GoJs?Java控制器传参至JSP页面展示方案
我来一步步帮你搞定这个需求,从后端传数据到前端用GoJS渲染再到详情展示,全流程给你捋清楚:
1. 后端Java控制器:把对象列表转成JSON传到JSP
首先得把你的对象列表转换成JSON格式——毕竟前端JavaScript能直接处理JSON。假设你的实体类是Entity,包含id、name、description、parentId这类字段(你可以根据实际结构调整),用Jackson库来序列化列表到JSON字符串就很方便:
import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.servlet.ModelAndView; import java.util.List; @Controller public class EntityController { @GetMapping("/show-diagram") public ModelAndView showDiagram() { ModelAndView mav = new ModelAndView("diagram-page"); // 你的JSP页面名称 List<Entity> entityList = getEntityList(); // 从数据库/业务层获取对象列表 // 转成JSON字符串 ObjectMapper mapper = new ObjectMapper(); String jsonData = mapper.writeValueAsString(entityList); mav.addObject("entityJson", jsonData); return mav; } // 模拟数据获取逻辑,替换成你的实际业务代码 private List<Entity> getEntityList() { return List.of( new Entity(1, "用户管理模块", "负责系统用户的增删改查", null), new Entity(2, "权限配置", "分配用户角色与操作权限", 1), new Entity(3, "日志记录", "记录用户操作行为", 1) ); } }
2. JSP页面:接收JSON并初始化GoJS
在JSP里先引入GoJS脚本,接着把后端传的JSON转成JS变量,然后构建GoJS图、定义节点模板,最后处理节点点击展示详情的逻辑:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>GoJS 实体详情展示</title> <!-- 引入GoJS --> <script src="https://unpkg.com/gojs/release/go.js"></script> <style> #myDiagramDiv { width: 800px; height: 500px; border: 1px solid #ccc; float: left; } #detailPanel { width: 300px; height: 500px; border: 1px solid #ccc; float: left; margin-left: 20px; padding: 15px; box-sizing: border-box; } </style> </head> <body> <div id="myDiagramDiv"></div> <div id="detailPanel">点击任意节点查看详情</div> <script> // 从后端获取JSON数据,用<c:out>转义避免语法错误和XSS风险 const entityData = JSON.parse('<c:out value="${entityJson}" />'); // 初始化GoJS Diagram const $ = go.GraphObject.make; const diagram = $(go.Diagram, "myDiagramDiv", { layout: $(go.TreeLayout, { angle: 90, layerSpacing: 80 }), // 树形布局,可按需更换 "undoManager.isEnabled": true }); // 定义节点模板,可自定义样式 diagram.nodeTemplate = $(go.Node, "Auto", $(go.Shape, "RoundedRectangle", { fill: "#5B9BD5", stroke: "#1E4D72", strokeWidth: 2 }, new go.Binding("fill", "isSelected", sel => sel ? "#FFA500" : "#5B9BD5").ofObject()), $(go.TextBlock, { margin: 12, font: "14px sans-serif", stroke: "white", wrap: go.TextBlock.WrapFit }, new go.Binding("text", "name")) ); // 定义链接模板(如果是关联结构需要,无关联可删除) diagram.linkTemplate = $(go.Link, $(go.Shape, { stroke: "#1E4D72", strokeWidth: 2 }), $(go.Shape, { toArrow: "Standard", fill: "#1E4D72", stroke: "#1E4D72" }) ); // 把实体数据转换成GoJS需要的节点/链接格式 const nodeDataArray = []; const linkDataArray = []; entityData.forEach(entity => { // 把所有详情字段存入节点数据,方便后续展示 nodeDataArray.push({ key: entity.id, name: entity.name, detail: { id: entity.id, name: entity.name, description: entity.description // 这里添加你需要展示的其他字段 } }); // 存在父节点时添加链接 if (entity.parentId != null) { linkDataArray.push({ from: entity.parentId, to: entity.id }); } }); // 加载数据到Diagram diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray); // 节点点击事件:展示详情到右侧面板 diagram.addDiagramListener("ObjectSingleClicked", e => { const detailPanel = document.getElementById("detailPanel"); const clickedNode = e.subject.part; if (clickedNode instanceof go.Node) { const detail = clickedNode.data.detail; // 渲染详情HTML let detailHtml = `<h3>${detail.name}</h3>`; detailHtml += `<p><strong>ID:</strong> ${detail.id}</p>`; detailHtml += `<p><strong>描述:</strong> ${detail.description}</p>`; // 其他字段继续补充... detailPanel.innerHTML = detailHtml; } else { detailPanel.innerHTML = "点击任意节点查看详情"; } }); </script> </body> </html>
3. 关键注意事项
- JSON转义:必须用
<c:out>输出后端传的JSON,避免引号、换行等字符导致JS语法错误,同时防止XSS攻击。 - GoJS数据格式:
GraphLinksModel需要节点数组(每个节点要有唯一key)和链接数组(每个链接要有from/to对应节点key);如果只是单纯展示列表,不用链接的话,换成Model即可。 - 布局选择:示例用的是树形布局,你可以换成
GridLayout(网格布局)、ForceDirectedLayout(力导向布局)等,根据你的展示需求调整。 - 详情展示:直接把所有详情字段存入节点数据,点击时就能快速渲染,比AJAX请求更高效;如果数据量极大,再考虑按需请求详情。
内容的提问来源于stack exchange,提问作者DILSHAD
相关产品推荐
相关产品推荐

