小言_互联网的博客

不会前端没事,用GWT Boot和Spring Boot构建Web程序

399人阅读  评论(0)

本文介绍了一种使用Java构建Web应用程序的方式,其中GWT或者J2CL是必不可少的,另外还有多个UI框架可以配套使用,比如Domino UIVueGWTGWT Material Design (GMD)React4JWebFX,还有一些活跃低的框架GWTBootstrap3RedHat PatternFly for Java

开始之前先看下LOVE(Learn Once Vse Everywhere) 架构。

1、Spring Boot Server: 提供服务端
2、Shared: 提供公共的API、接口、验证类或实体类等
3、Client: GWT Boot 是GWT的等效框架,就如同Spring Boot 和 Spring Framework

创建Spring Boot后端服务

使用Spring Initializr 创建Spring Boot项目。建立如下文件:
PersonController、PersonService、PersonRepository、Person实体

源码地址:
https://github.com/gwtboot/intro-gwtboot-springboot/tree/main/intro-gwtboot-springboot-server

创建共享模块

共享服务,用于客户端和后端服务之间共享API、验证、异常类等,这里可以自己决定哪些类要共享。

由于GWT Boot 客户端需要使用源码编译成JavaScript,共享模块要使用Maven Source plugin导出共享模块源码包。

分离出共享模块后,将它作为依赖项添加到后端服务中。

另外我们创建一个“Module”.gwt.xml文件,用来转换共享模块的源代码,该文件声明了要转换的包目录,在该例中是shared包下的所有Java文件。

GWT Boot 客户端

这一部分是最有趣的部分,这里我们将使用DominoUI作为前端创建客户端。
使用GWT Boot Maven Archetype创建:

mvn archetype:generate -DarchetypeGroupId=com.github.gwtboot \
                       -DarchetypeArtifactId=gwt-boot-ui-domino-dagger2-archetype \
                       -DarchetypeVersion=1.0.0 \
                       -DgroupId=com.company.crm \
                       -DartifactId=intro-gwtboot-springboot-client \
                       -Dversion=1.0.0-SNAPSHOT

生成的是一个Todo List 的应用程序,可以直接运行。

现在将上面创建的共享模块依赖和源码添加到该客户端模块中。

随后在客户端模块module.gwt.xml中添加Person.gwt.xml文件

GWT Maven plugin 根据module.gwt.xml 创建真正的GMT 模块 App.gwt.xml

后面,我们开始对页面进行布局,将创建如下样式页面:

Web 布局

默认的DominoUI布局有:导航栏-1、2、3,左侧面板-4,中间面板-5,隐藏页脚-6和隐藏右侧面板。

可以使用removeLeftPanel方法删除左侧面板。

Layout layout = Layout.create(CONSTANTS.appTitle()).removeLeftPanel()
    .show(Theme.BLUE);

现在考虑一下我们应该怎么用DominoUI来实现如下布局

为了创建这个UI视图,我们使用三个类:HomeClientBundle、HomeView和HomeComposite,它们是用MVP(Model View Presenter)模式设计的。


HomeClientBundle:一个GWT客户端捆绑包,它将图像、CSS和JavaScript等多种资源组合到一个文件中,以便浏览器高效加载。

HomeView:此类负责创建整体布局和所有其他UI元素,这些元素将在presenter/composite中使用。

HomeComposite:此类处理表示逻辑,并根据PersonListGroup中的人数创建不同类型的对话框,如警告或错误对话框。

void handleCheckOkClick(PersonDto person) {
   
  personListGroup.removeItem(person);

  int size = personListGroup.getItems().size();
  if (size == 2) {
   
    createWarningDialog();
  } else if (size == 0) {
   
    createErrorDialog("Error on personListGroup is empty!");
  }

  donePersonListGroup.addItem(person);
 }

运行Web

1、模拟运行
首先转到客户端模块目录

mvn gwt:generate-module gwt:devmode -Pdevelopment-mock

可以修改代码后,立即在浏览器上看到转换后的JavaScript效果

2、使用server运行

-- 首先转到客户端模块目录
mvn gwt:generate-module gwt:devmode -- 客户端

-- 首先转到服务端模块目录
mvn spring-boot:run -- 服务端

部署Web

可以将客户端静态资源打包到Spring Boot static目录中,作为单体应用部署。

1、Client:使用 Maven Assembly plugin插件和distribution.xml文件,这会创建一个intro-gwtboot-springboot-client-1.0.0-SNAPSHOT-javascript.jar
2、Server:将打包出来的文件解压到static目录下,由于路径发生了变化,需要再server中创建一个index.html,内容如下

  <!-- All files in directory app, see screenshot below -->
  <link type="text/css" rel="stylesheet" href="app/css/domino-ui.css">
  <link type="text/css" rel="stylesheet" href="app/css/themes/all-themes.css">
  <title>Demo GWT Webapp with DominoUI and Dagger2</title>
                                        
  <script type="text/javascript" src="app/app.nocache.js" async=""></script>

使用如下命令运行:

-- 转到服务端模块目录
java -jar target/intro-gwtboot-springboot-server-1.0.0-SNAPSHOT.jar

-- 使用该地址访问web应用
http://localhost:9090/intro/

参考资料
[1] Domino UI: https://demo.dominokit.org/home
[2] VueGWT: https://vuegwt.github.io/vue-gwt/guide/#features
[3] GWT Material Design (GMD): https://gwtmaterialdesign.github.io/gmd-core-demo/
[4] React4J: https://react4j.github.io/
[5] WebFX: https://webfx.dev/
[6] GWTBootstrap3: https://github.com/treblereel/gwtbootstrap3
[7] RedHat PatternFly for Java: https://patternfly-java.github.io/showcase/#documentation:alert
[8] GWT Boot https://github.com/gwtboot

作者其他文章:
《Prometheus+Grafana 实践派》专栏火热更新中

  1. Grafana 的介绍和安装
  2. Grafana监控大屏配置参数介绍(一)
  3. Grafana监控大屏配置参数介绍(二)
  4. Grafana监控大屏可视化图表
  5. Grafana 查询数据和转换数据
  6. Grafana 告警模块介绍
  7. Grafana 告警接入飞书通知

转载:https://blog.csdn.net/weixin_40972073/article/details/129192687
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场