Jmix 如何将外部数据直接显示在界面?

企业级应用中,通常一个业务系统并不是孤立存在的,而是需要与企业、部门或者是外部的已有系统进行集成。一般而言,系统集成的数据和接口交互方式通常有以下几种:
- 文件传输:通过文件传输的方式将数据传递给其他系统,例如使用 FTP 或 SFTP 等协议传送文件。这种交互方式适合单向或批量数据传输。
- Web 服务 API:使用 API 与其他系统进行通信,一般采用 SOAP 或 REST 等通信协议。这种交互方式可用于实现单向或双向数据传输。
- 数据库交互:使用数据库共享的方式,或者通过数据库连接进行数据交换。这种交互方式在双向数据同步和实时数据交换方面非常有效。但是一定要注意数据权限控制和数据安全。
- 消息队列:通过消息队列进行数据的收发,而无需与其他系统直接通信。消息队列可用于处理大量数据以及异步数据传输的情况。
不论使用那种方式进行通信和传输,在主系统(即,正在实施的系统)中,还需要考虑的一个问题是,第三方系统过来的数据需不需要保存?如果主系统要基于接入的数据进行进一步处理,则通常需要保存数据。而有时候由于数据安全方面的原因,亦或是考虑到本地存储数据后还存在数据同步与重复存储的问题,第三方系统的数据过来后,主系统并不需要存储数据,只是提供展示和操作界面。
本文中,我们以常见的 REST API 通信为例,看看 Jmix 应用是如何直接使用外部数据的(这里我们不存储外部数据)。
外部数据源
我们假设外部数据源通过 REST API 提供关于项目(project)和任务(task)的 CRUD 接口。
定义 DTO 和 Service
首先,我们在主系统中定义两个 DTO 实体:Project 和 Task,用 Jmix Studio 可以直接创建 DTO 实体:

然后,在主系统中我们需要定义两个 Services,专门用来对 Project 和 Task 实体进行 CRUD 操作,而这些操作里面,其实是调用了外部系统提供的 REST 接口,以 TaskService 为例:
@Component
public class TaskService {
public static final String TASKS_BASE_URL = "http://localhost:18080/tasks";
@Autowired
private RestTemplate restTemplate;
public List<Task> loadTasks() {
Task[] tasks = restTemplate.getForObject(TASKS_BASE_URL, Task[].class);
return Arrays.asList(tasks);
}
public Task saveTask(Task task) {
String url = task.getId() != null ?
TASKS_BASE_URL + "/" + task.getId() :
TASKS_BASE_URL;
ResponseEntity<Task> response = restTemplate.postForEntity(url, task, Task.class);
return response.getBody();
}
public void deleteTask(Task task) {
restTemplate.delete(TASKS_BASE_URL + "/" + task.getId());
}
}
Project DTO 的创建过程和 ProjectService 的内容与上面步骤类似,这里就不再赘述。
第一种方式:使用代理
第一种方式是使用数据加载代理和提交代理方法,将原本使用 DataManager 进行数据加载和写入的相应方法替换为使用我们自定义的服务:

这里,我们选择 Task DTO 和它的列表页和编辑页作为示例。
首先,在列表页添加数据加载的代理,在界面选中数据加载器后,双击代理方法中的 <empty> 标签,Studio 会自动生成方法并跳转到方法定义,添加自定义逻辑:

然后,在编辑页添加数据提交代理,这里需要在 XML 中选中 data 节点,然后双击生成 commitDelegate:

这样就完成了我们需要实现的功能。是不是很简单?
第二种方式:自定义数据存储
Jmix 中,数据存储可以进行自定义,通过自定义的数据存储,可以像处理 JPA 实体一样,使用 DataManager 处理 DTO 实体。在检测到 DTO 实体关联到某个自定义存储后,DataManager 会将 CRUD 操作都通过代理执行,并且能处理对 DTO 实体的引用。具体实现框架如下:

可以看到,使用这种方式不需要对界面中的实体操作进行拦截,而是将所有对于外部系统的接口调用都交给 DataManager 通过数据存储进行分发。
这里,我们选择 Project DTO 作为示例,创建相应的数据存储:
- 创建
ProjectDataStore实现DataStore接口:
@Component("sample_ProjectDataStore")
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class ProjectDataStore implements DataStore {
// 注入 ProjectService 用于具体的操作
@Autowired
private ProjectService projectService;
// 后面需要实现接口中的方法,主要是通过 projectService 对数据进行 CRUD,这里省略。
...
}
- 创建一个实现
StoreDescriptor接口的类。必须是一个 Spring 单例 bean,其中getBeanName()方法必须返回上一步创建的 bean 的名称:
@Component("sample_ProjectDataStoreDescriptor")
public class ProjectDataStoreDescriptor implements StoreDescriptor {
@Override
public String getBeanName() {
return "sample_ProjectDataStore";
}
@Override
public boolean isJpa() {
return false;
}
}
- 在
application.properties中添加对数据存储的配置:
# 如果有多个,则以逗号分隔
jmix.core.additional-stores = projectds
# 配置名称为 jmix.core.storeDescriptor_<store_name>
jmix.core.store-descriptor_projectds = sample_ProjectDataStoreDescriptor
- 为
Project实体添加@Store注解:
@Store(name = "projectds")
@JmixEntity
public class Project {
...
}
通过这几步,我们完成了数据存储的实现和配置。Project 的列表页和编辑也不需要做任何改动,并且,任何通过 DataManager 对 Project DTO 的操作就像操作 JPA 实体一样方便,可以在服务层和 UI 层调用。
结论
如果外部 API 提供了丰富的操作接口,比如 CRUD、分页、排序甚至支持某种查询语言,那么我们推荐创建一个自定义的数据存储。这种为数据操作 Service 提供自定义数据存储的方式,更贴近 Jmix 原生的开发方式。另外,如果需要的话,自定义的数据存储也可以继承 AbstractDataStore 类,这个类是 Jmix 内置 JpaDataStore 的父类。通过这个类派生可以使用框架提供的一些机制,比如数据访问安全和对外部数据的审计。
但是如果外部 API 只提供了几个简单的接口,这种情况我们建议直接在 UI 层使用数据读写代理的方式。
示例的完整代码请访问 GitHub。
Jmix 如何将外部数据直接显示在界面?的更多相关文章
- Postman高级应用——流程控制、调试、公共函数、外部数据文件
postman客户端下载地址:https://www.getpostman.com/apps 目录 流程控制 调试 公共函数 外部数据文件 流程控制 流程控制简言之就是设置接口的执行顺序,流程控制只有 ...
- 【Social listening实操】作为一个合格的“增长黑客”,你还得重视外部数据的分析!
本文转自知乎 作者:苏格兰折耳喵 ----------------------------------------------------- 在本文中,作者引出了"外部数据"这一概 ...
- ORACLE-SQLLOAD导入外部数据详解
今天公司需要把外部文本的一些数据导入到数据库.这里把相关步骤和注意的地方记录,供需要的人参考学习!这里的环境是在windows下的数据库,linux或者其他数据库同理! 1.准备工作:创建需要导入数据 ...
- pandas外部数据的读取构造数据框-文本文件读取(一种utf-8中文编码乱码处理经验)
上面一篇文章有记录pandas构造数据框的方式有二维数组,字典,嵌套的列表和元组等,本篇用于介绍通过外部数据读取的方式来构造数据框. python读取外部数据集的时候,这些数据集可能包含在文本文件(c ...
- Excel中外部数据链接无法删除的解决方法【转】
[摘要] 当Excel中公式引用了外部数据,每次打开时,总是自动弹出自动更新链接的对话框.如何找到这些链接?有没有办法实现断开原有链接,而保持数值不变? 有客户反应,当Excel无法链接到外部数据后, ...
- k8s env、configmap、secret外部数据加载配置
K8s提供了多种外部数据注入容器的方式,今天我们主要学习环境变量.ConfigMap以及Secret的使用和配置. 环境变量 在docker项目中,对一个容器添加环境变量可以在容器创建时通过-e EN ...
- BPM配置故事之案例10-获取外部数据
老李:Hi,小明,我又来了 小明:--这次又怎么了. 老李:之前的物资管理方式太混乱了,这段时间我整理了采购物资清单,现在都录入到我们的ERP中了,以后申请物资改成从ERP数据选择吧.物资明细表我也做 ...
- EXTJS中grid的数据特殊显示,不同窗口的数据传递
//EXTJS中grid的数据特殊显示renderer : function(value, metaData, record, rowIndex, colIndex, store, view) { v ...
- android 从服务器获取新闻数据并显示在客户端
新闻客户端案例 第一次进入新闻客户端需要请求服务器获取新闻数据,做listview的展示, 为了第二次再次打开新闻客户端时能快速显示新闻,需要将数据缓存到数据库中,下次打开可以直接去数据库中获取新闻直 ...
- input中空格后的数据不显示
bug,input中空格后的数据不显示 昨天在修bug,有一个bug是用户修改的个人信息的地址栏,输入有空格的话,空格后面的内容存不上,而且没有报错,奇怪了,只好跟踪下. 页面上的输入框就是个 ...
随机推荐
- Jmeter四、jmeter脚本组成和组件搭配
一.jmeter脚本开发原则 简单:去除无关的组件,同时能复用的尽量复用. 正确:对脚本或者业务正确性进行必要的判断,不能少也不能多(200) 高效:部分组件仅仅在脚本开发模式使用,在真正生产环境下不 ...
- python3GUI--轮播图效果展示By:PyQt5(附源码下载地址)
@ 目录 一.前言 二.展示 1.酷我音乐 2.QQ飞车 3.虎牙 4.网易云音乐 5.英雄联盟 6.英雄联盟(Pro) 7.腾讯视频 三.源代码 1.demo02GUI.py 2.engine.py ...
- 阿里云Linux服务器安装Maven实战教程
下载地址 https://maven.apache.org/download.cgi 文件上传 把下载的文件上传到阿里云服务器 /usr/local/software 的目录(使用工具) window ...
- JAVA、Tomcat服务器
JAVA如何配置服务器 Tomcat服务器: 1.Web开发中的常见概念: (1)B/S系统和C/S系统 Brower/Server:浏览器 服务器 系统 ----- 网站 Client/Server ...
- Spring Boot统一日志框架
一.日志框架的选择 市面上常见的日志框架有很多,它们可以被分为两类:日志门面(日志抽象层)和日志实现,如下表. 日志分类 描述 举例 日志门面(日志抽象层) 为 Java 日志访问提供一套标准和规范 ...
- 用python写xml文件
def writeInfoToXml(filename, config_id, obj_name): from xml.dom.minidom import Document ''' eg: < ...
- 用appium来操作模拟器
1 import time 2 from appium import webdriver 3 from selenium.webdriver.common.by import By 4 from se ...
- SQL SERVER 内存优化表踩坑记
背景 因为生产应用需要刷新大量的状态数据到数据库中用于客户端的显示,于是新建了一张状态表,表内行数固定,状态更新到列内.刚开始运行时还行,更新都很及时,查询速度也不慢.于是就这样使用了有一个月的时间. ...
- 7&的2022年终总结
7&的2022年终总结 文章目录 7&的2022年终总结 1.前言 2.技术 3.生活 4.展望未来 博客搬家的需要: var code = "49d515c3-0238-4 ...
- 前端访问Tornado跨域问题