非云Confluence插件开发:如何通过Atlassian框架访问数据库?
Confluence 非云版插件:自定义SQL查询功能实现指南
1. atlassian-plugin.xml 核心配置
依赖与权限声明
- REST端点配置:限制仅管理员访问,确保数据库操作的安全性
<rest name="Custom SQL Endpoint" key="custom-sql-rest" path="/custom-sql" version="1.0"> <description>执行自定义SQL查询的后端接口</description> <package>com.yourcompany.confluence.plugins.customsql.rest</package> <permission>administer-confluence</permission> </rest>
- 管理员页面挂载:将查询UI嵌入Confluence全局设置页面
<web-panel key="custom-sql-admin-panel" location="system.admin/globalsettings" weight="100"> <description>管理员自定义SQL查询面板</description> <label>自定义SQL查询</label> <resource type="velocity" name="view" location="/templates/custom-sql-admin.vm"/> <permission>administer-confluence</permission> </web-panel>
2. 数据库访问实现(替代Jira的Manager类)
Confluence基于Hibernate而非OFBiz,推荐以下两种标准方式:
方式1:Hibernate会话管理器(推荐)
注入HibernateSessionManager获取会话,执行原生SQL:
import com.atlassian.confluence.core.persistence.hibernate.HibernateSessionManager; import com.atlassian.sal.api.transaction.TransactionTemplate; import org.springframework.beans.factory.annotation.Autowired; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.Consumes; import javax.ws.rs.core.MediaType; import java.util.List; import java.util.Map; @Path("/query") public class CustomSqlResource { private final HibernateSessionManager hibernateSessionManager; private final TransactionTemplate transactionTemplate; @Autowired public CustomSqlResource(HibernateSessionManager hibernateSessionManager, TransactionTemplate transactionTemplate) { this.hibernateSessionManager = hibernateSessionManager; this.transactionTemplate = transactionTemplate; } @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public List<Map<String, Object>> executeSql(Map<String, String> request) { String sql = request.get("sql"); // 强制校验:仅允许SELECT查询,防止数据破坏 if (!sql.trim().toUpperCase().startsWith("SELECT")) { throw new IllegalArgumentException("仅支持SELECT查询"); } // 事务内执行,避免连接泄漏 return transactionTemplate.execute(() -> { return hibernateSessionManager.getSession() .createNativeQuery(sql) .setResultTransformer(org.hibernate.transform.AliasToEntityMapResultTransformer.INSTANCE) .list(); }); } }
方式2:直接使用DataSource(不推荐)
若需JDBC原生操作,可注入javax.sql.DataSource,但需自行管理连接和事务:
import javax.sql.DataSource; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; // 注入DataSource后执行查询
3. 前端UI实现(Velocity模板)
创建/templates/custom-sql-admin.vm,实现SQL输入、执行按钮和结果表格渲染:
<div class="aui-page-panel"> <h2>自定义SQL查询工具</h2> <div class="aui-group"> <textarea id="sqlQuery" class="aui-textarea" rows="5" placeholder="输入SELECT查询语句..."></textarea> </div> <div class="aui-group"> <button id="executeBtn" class="aui-button aui-button-primary">执行查询</button> </div> <div id="resultContainer" class="aui-group" style="margin-top: 20px; display: none;"> <h3>查询结果</h3> <table id="resultTable" class="aui aui-table-stripes"></table> </div> </div> <script> AJS.toInit(function() { AJS.$("#executeBtn").click(function() { var sql = AJS.$("#sqlQuery").val().trim(); if (!sql) { AJS.messages.error({title: "错误", body: "请输入SQL查询语句", container: "#resultContainer"}); return; } AJS.$.ajax({ url: AJS.contextPath() + "/rest/custom-sql/1.0/query", type: "POST", contentType: "application/json", data: JSON.stringify({sql: sql}), success: function(data) { var table = AJS.$("#resultTable").empty(); if (data.length === 0) { table.append("<tr><td colspan='100%'>无查询结果</td></tr>"); } else { // 构建表头 var headers = Object.keys(data[0]); var headerRow = "<tr>" + headers.map(h => `<th>${h}</th>`).join("") + "</tr>"; table.append(headerRow); // 构建数据行 data.forEach(row => { var dataRow = "<tr>" + headers.map(h => `<td>${row[h] || ""}</td>`).join("") + "</tr>"; table.append(dataRow); }); } AJS.$("#resultContainer").show(); }, error: function(xhr) { AJS.messages.error({title: "执行失败", body: xhr.responseText || "查询执行出错", container: "#resultContainer"}); AJS.$("#resultContainer").show(); } }); }); }); </script>
4. 关键注意事项
- SQL注入防护:必须限制仅允许SELECT操作,禁止DDL/DML语句,避免数据库被恶意修改
- 事务管理:所有数据库操作需通过
TransactionTemplate包裹,防止连接泄漏和数据不一致 - 权限控制:所有UI和REST端点必须添加
administer-confluence权限校验,仅开放给管理员 - 版本兼容性:不同Confluence版本的Hibernate依赖可能不同,需在pom.xml中匹配对应版本的
confluence-core依赖
内容的提问来源于stack exchange,提问作者MIkailK
相关产品推荐
相关产品推荐

