翻译者:萧正楠
Hilla是如前所述 Vaadin Fusion,紧密结合了积极响应式 JavaScript 后端和 Spring Java 后端,用作全栈 Web 合作开发的架构。
Hilla将如前所述 Spring 的 Java 后端与采用 Lit 构筑的 TypeScript 后端并重,该处提及的Lit是一类加速、积极响应式的 JavaScript 架构。如前所述 Vaadin Fusion 的 Hilla 是 Java 生态控制系统中的一类独有架构:近似于 JavaScript 的 Next.js,不同之处是Hillary是如前所述 Spring 的 Java 后端。责任编辑将协助你早已开始采用 Hilla,主要包括怎样构筑基本上的Web 应用程序、构筑后端和加进新模块。
Hilla and Vaadin
在去年1 月,Vaadin 的合作开发者正式宣布将 Vaadin Fusion 重新重新命名为 Hilla。对早已熟识 Fusion 的合作开发者而言,而已中文名称出现了变动。对才刚自学 Hilla 的合作开发者,会注意到责任编辑中的实例中采用的包和模块都是以 Vaadin 重新命名的。但在之后的版中Vaadin Fusion 应用软件都Sonbhadra以 Hilla 重新重新命名。
具备积极响应式后端的 Java Web 合作开发
Hilla 将积极响应式 JavaScript 后端和 Spring Java 后端资源整合到两个标准化的构筑中。责任编辑中的实例Sonbhadra表明那些模块是怎样相互配合的,以此来如是说Hilla全栈架构。在早已开始增容前,你须要在控制系统上加装 Node.js (npm)和新一代的 JDK。保证 node -v 和 java version 都能组织工作!
具体而言,关上配置文件并透过 npx 构筑两个新项目,如目录1 右图。
目录1.在 Hilla 中构筑两个新项目
拷贝
npx @vaadin/cli init –hilla foundry-hilla1.
现在, cd进入新目录,然后键入./mvnw(或mvnw 对 Windows)。此命令启动 Maven 的构筑。你将看到正在构筑的后端和后端的输出日志记录。很快,该插件将启动并在合作开发模式下运行。
图1.访问 localhost:8080,你应该会看到你的 Hilla 插件启动并运行
如果你看一下你才刚构筑的文件控制系统,你会看到结构分为标准的 Maven 结构和后端目录:
项目根目录包含 Maven 构筑文件(pom.xml),它将 Java 代码从/src 构筑到/target,并调用 JavaScript 构筑工具(vite.js)来构筑包含在/frontend 中的后端插件。
构筑后端
在 Hilla 中,后端是从/front-end/index.html、/front-end/index.ts和routes.ts文件中引导的。那些文件一起确定路由并将内容设置到给定路由的页面。那些页面中最具启发性的是routes.ts,如目录2 右图。
目录2.Routes.ts
拷贝
import { Route } from @vaadin/router;import ./views/helloworld/hello-world-view;import ./views/main-layout;export type ViewRoute = Route &{ title?: string; icon?: string; children?: ViewRoute[];};export const views: ViewRoute[]= [// place routes below (more info https://vaadin.com/docs/latest/fusion/routing/overview){ path:, component:hello-world-view, icon:, title:,},{ path:hello, component:hello-world-view, icon:la la-globe, title:Hello World,},{ path:about, component:about-view, icon:la la-file, title:About, action: async (context, command)=>{ await import(./views/about/about-view); return;},},];export const routes: ViewRoute[]= [{ path:, component:main-layout, children:[…views],},];1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.
目录2 中的代码将路径与模块相关联。与许多 JavaScript 架构一样,Hilla 采用模块来表示视图。在这种情况下,当用户转到空白路线时,它将提供hello-world-view模块。(请注意,其他路线提供额外的信息,如图标、标题和操作。)
主布局由/frontend/views/main-layout.ts 处理,而 hello-world-view 的内容在/frontend/views/helloworld/hello-world-view.ts 中,如目录3 右图。
目录3. hello-world-view.ts
拷贝
import @vaadin/button;import @vaadin/notification;import { Notification } from @vaadin/notification;import @vaadin/text-field;import { html } from lit;import { customElement } from lit/decorators.js;import { View } from ../../views/view;@customElement(hello-world-view)export class HelloWorldView extends View { name =; connectedCallback(){ super.connectedCallback(); this.classList.add(flex,p-m,gap-m,items-end);} render(){ return html Say hello; } nameChanged(e: CustomEvent){ this.name = e.detail.value;} sayHello(){ Notification.show(Hello ${this.name});}}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.
Lit 的如是说。该render()方法负责输出视图的内容。我们将在这里用它搜索某个事物。特别是,我们想看看怎样将这个后端与我们的后端 Java 端点连接起来。
创建 Java 端点
Hilla 构筑在 Spring Boot 之上,因此我们能像往常一样采用 Spring Web构筑端点。Hilla 提供了额外的功能来自动生成将在 Lit 后端采用的 TypeScript。
/src/java/main/com/example/application具体而言在被调用的文件中创建两个新文件MyEndpoint.java。将目录4 的内容粘贴到该文件中。
目录4. MyEndpoint.java
拷贝
package com.example.application;import com.vaadin.flow.server.auth.AnonymousAllowed;import dev.hilla.Endpoint;import dev.hilla.Nonnull;@Endpoint@AnonymousAllowedPublic @Nonnull class MyEndpoint { public String foo(){ return “bar”;}}1.2.3.4.5.6.7.8.9.10.11.12.13.
Hilla 的@Endpoint注释告诉架构这个类是两个 REST API。该类也使用注解进行@AnonymousAllowed注解,因为默认情况下,Hilla 透过 Spring 安全性保护所有端点。@Nonnull注释为后端 TypeScript 生成正确的类型绑定。
保存这个类文件后,你能观察到 Hilla 早已在/frontend/generated/MyEndpoint.ts 中生成了两个新的 TypeScript 文件。我们将采用这个模块从视图中点击端点。
注意:不要对那些生成的文件进行更改;Hilla 将根据对 Java 文件的更改覆盖它们。
现在,返回到 frontend/views/helloworld/hello-world-view.ts,我们将在这里采用我们的简单端点。在这种情况下,我们想要输出须要调用 foo()端点(即“bar”)的内容。目录5 显示了你应该对 hello-world-view.ts 文件进行的加进。(请注意,我早已删除了大部分以前的代码,只留下了这个目录的附加内容。)
目录5. Hello-world-view.ts
拷贝
//…import { customElement,property } from lit/decorators.js;import { foo } from Frontend/generated/MyEndpoint;@customElement(hello-world-view)export class HelloWorldView extends View {//…@property() myString: string =””; constructor(){ super(); this.getString();} render(){ return html //…
这里的要点是从 MyEndpoint 模块中导入 foo()函数,然后采用它来调用我们之前定义的远程后端 Java 方法。
为此,我们采用 Lit TypeScript 注释@property 在类上定义了两个反应属性,中文名称为string。我们将采用此属性来存储来自服务器的值。为了填充它,我们调用 async getString()方法,该方法简单地调用 foo()函数,并将返回值放入 myString。
此我们不必考虑太多。
在 Hilla 中采用 Vaadin 模块
正如我之前提及的,Hilla 是 Vaadin Fusion,因此采用 Hilla 构筑的插件能利用你可能从该架构中了解的所有精心设计的模块。例如,让我们采用 Vaadin 网格模块来加载带有标题和作者的小说集。
具体而言,我们将创建两个模型对象,它只包含两个字符串,如目录6 右图。这个文件是两个典型的 Java 数据对象。将其保存为/src/main/java/com/example/application/Novel.java。
目录6.用作存储小说的模型对象
拷贝
package com.example.application;import javax.validation.constraints.NotBlank;public class Novel {@NotBlank private String title;@NotBlank private String author; public Novel(String title, String author){ this.title = title; this.author = author;} public String getTitle(){ return title;} public void setTitle(String title){ this.title = title;} public String getAuthor(){ return author;} public void setAuthor(String author){ this.author = author;}}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.
在目录7 中,我们提供来自 MyEndpoint 的小说列表。
目录7.带有我最喜欢的小说列表的 MyEndpoint
拷贝
package com.example.application;import java.util.*;import java.util.ArrayList;import java.util.List;import com.vaadin.flow.server.auth.AnonymousAllowed;import dev.hilla.Endpoint;import dev.hilla.Nonnull;@Endpoint@AnonymousAllowedpublic class MyEndpoint { private final List novels = new ArrayList(); MyEndpoint(){ Novel empireFalls = new Novel(“Empire Falls”,”Richard Russo”); Novel reservationBlues = new Novel(“Reservation Blues”,”Sherman Alexie”); Novel theAthenianMurders = new Novel(“The Athenian Murders”,”Jos Carlos Somoza”); this.novels.add(empireFalls); this.novels.add(reservationBlues); this.novels.add(theAthenianMurders);} public @Nonnull List getNovels(){ return this.novels;}}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.
在目录7 中,我们准备了几本带有作者的小说,并将它们插入到 novels 属性中。然后我们在 getNovels()端点中公开数据。
现在,让我们显示新数据,如目录8 右图。(请注意,目录8 只显示了代码的更改部分。)
目录8.采用网格显示小说
拷贝
//…import { foo, getNovels } from Frontend/generated/MyEndpoint;import @vaadin/grid/vaadin-grid;@customElement(hello-world-view)export class HelloWorldView extends View {@property() novels: object ={}; constructor(){ //… this.initNovels();} render(){ return html ; } async initNovels(){ this.novels = await getNovels();}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.
在此目录中
接下来,我们采用 this.novels 为导入的 vaadin-grid 模块提供.items 属性。最终结果是两个格式良好的网格模块,而且组织工作量很小。
结语
责任编辑如是说了如前所述 Vaadin Fusion 的全栈架构 Hilla。Hilla 为采用积极响应式后端构筑 Java Web 插件提供了良好的集成体验。多亏了Vaadin,它有许多有用的模块可供采用。责任编辑实例应该会让你对Hilla的采用有两个初步的了解。