# 如何使用 Java EE 和 Angular 構建單頁應用程序
> 原文: [https://javatutorial.net/how-to-build-single-page-application-with-java-ee-and-angular](https://javatutorial.net/how-to-build-single-page-application-with-java-ee-and-angular)
本文介紹如何使用 Angular 和 Java EE 構建自己的單頁應用程序
網絡世界一直令人眼花亂。 如今,可見網絡上有超過 18 億個頁面,其中大多數頁面提供了某種想法,業務,原因或互聯網上您擁有的任何內容。 每天都有越來越多的人對 Web 感興趣,而第二者正在創建內容。 然后,您可以了解為什么 Web 開發是目前最繁榮的工作之一。 該技術本身正在迅速發展,以滿足用戶的需求,并通過更好的沉浸式用戶體驗超越了它。 這種追求促使 SPA 等技術成為行業領先的技術。 他們的增長驚人,用戶似乎對新的升級感到非常滿意。 今天,我們將使用 Angular 和 Java EE 構建自己的單頁應用程序,為您自己的實現奠定基礎。

[圖像源](https://koukia.ca/going-single-page-app-or-traditional-web-app-cedb10041b50)
## 什么是 SPA?
單頁應用程序是一種設計模式,特別是一種確定程序流程的架構設計模式。 這樣做的想法是一次加載所有數據和元素,以防止在用戶使用頁面時刷新頁面。 例如,您可能已經注意到,首次加載 Gmail 后,它甚至可以脫機運行,而且運行速度也很快。 Gmail,Facebook,GitHub 和許多其他應用程序使用 SPA 來提供自然的 UX,以保持不受干擾的用法。 如今,這種想法已逐漸發展為一種設計方向,PWA 則采用了相同的概念,即提供幾乎自然的離線體驗。

傳統頁面生命周期與 SPA 生命周期
[圖像源](https://msdn.microsoft.com/en-us/magazine/dn463786.aspx)
實際上,SPA 的許多優點使其成為開發人員的青睞選擇。
例如,使用 SPA,隨著編寫服務器渲染代碼的需求隨著 SPA 的消失,開發過程變得越來越容易。 SPA 應用程序直接呈現到瀏覽器。 將移動應用程序與您的應用程序集成起來比較容易,因為您可以使用相同的網絡后端。 當然,大多數資源(如 HTML,CSS 和腳本)在應用程序的生命周期內僅加載一次,這一事實使應用程序變得更快,因為僅在需要時來回傳輸數據。 這全都歸功于 JavaScript 框架為我們完成了大部分繁重的工作。
使用 SPA 確實有一些弊端,例如 SEO 變得有些難以管理,但是在完成應用程序后,我們將討論如何解決該問題。 今天要使用的框架是著名的 Angular。
## 為什么要 Angular?
好吧,您可能想知道為什么每個人都對 Angular 狂熱。 畢竟,目前的排名表明 Angular 是 JS 框架王國的統治者。 它是迄今為止使用最廣泛的框架,并且擁有最大的社區之一和大量文檔。 Angular 允許我們使用雙向數據綁定來構建動態 Web 應用程序。 在電子商務網站上瀏覽時,您不想每次簽出新產品或同一產品的其他版本時都重新加載頁面,而 Angular 允許您這樣做。 它也很容易構建和調試,因此使用 Angular 可以使測試變得更加容易,這是 Web 開發的核心步驟。 為此,互聯網上有許多 [Angular 教程](https://hackr.io/tutorials/learn-angular)和課程,可以從中找到基本信息。
## 為什么選擇 Java EE?
Java 企業版是健壯的技術和 API 的分組集合,用于企業級別,以構建可滿足關鍵業務需求和約束的可伸縮,事務性和分布式應用程序。 它旨在使 Java 開發保持最新狀態,以滿足當今應用程序的標準。 [Java EE](https://javatutorial.net/category/java-ee) 帶有大量的規范,可以滿足您的需求。 這就是為什么 Java EE 是理想的開始我們創建第一個 SPA 的旅程的原因。 我們將使用 Java 為 Angular 前端創建 REST 服務以供使用。
因此,讓我們開始吧。 我們將設計一個簡單的應用程序,在表格中顯示演員姓名及其著名的昵稱。 請注意,為了避免將本文變成 Java/Angular 課程,并且將重點放在 SPA 開發上,將省略一些代碼。
## 后端
Java 持久化 API 將使我們能夠管理和操縱應用程序和服務器之間的數據。 通過使用`@Entity`注解,我們可以將對象類建模為數據庫內部的數據庫實體。 您可能已經猜到`@ID`為此關系設置了主鍵,這是事實。 我們可以使用`@table`表示法來指定某些表屬性,例如唯一性約束(數據成員必須是唯一的,即候選鍵)和表名。 `@namedqueries`允許我們準備某些查詢以用于該關系。 然后,我們繼續使用構造函數,setter 和 getter 構建基本類。

演員實體類
我們首先創建 JPA 所需的`persistence.xml`文件,它看起來像這樣。 `javax.persistence.schema-generation`不僅使我們能夠以自然的方式運行 SQL,而且還可以連接到數據源(如果我們尚未連接到 SQL 源)。 因此,這樣做可以省去您的麻煩。

`persistence.xml`文件
這里要做的一件事是創建`Resources`類,以將該數據庫公開為資源類。`@Get`表示法定義 HTTP Get 謂詞行為,并以一種非常不錯的方式格式化 JSON 響應。

網絡服務類
## 前端
現在該跳到我們的前端了。 我們將分兩個步驟進行操作,首先是 HTML 文件,因為 Angular 擴展了典型的 HTML,并允許我們按照 MVC 設計,使用 Javascript 變量向組件添加自定義數據綁定。
HTML 文件中沒有太多代碼,這使 Angular 相當有效。 Angular 擁有我們將在此處使用的網格組件,Bootstrap 還提供了外觀漂亮的組件集,可供我們使用。

Angular HTML 文件
現在剩下的唯一事情就是制作一個 Javascript 文件,將所有內容整合在一起。
Javascript 文件將定義客戶端行為,并使用我們之前創建的 REST 服務發出 HTTP 請求。 這是程序中真正魔術的體現。

Angular 代碼
## Angular SEO 優化
SPA 的核心問題之一是 SEO 優化,這對于某些 SPA 的成功至關重要。 Google 在抓取 Javascript 內容時遇到了問題,盡管他們正在努力,但它還不完全兼容 JS。 有多種方法可以解決此問題,可以手動或使用自定義服務。 這個想法是從您的應用程序創建一個 HTML 快照以直接提供給搜尋器,而不是希望它可以正確理解和索引您的 Angular 代碼。 如果您無法手動完成任務,也可以減輕壓力,則可以使用預渲染平臺來完成任務。 您還可以執行一些輔助操作,例如獲取有意義的 URL 名稱而不是隨機生成的 URL 名稱。 維護用戶友好的 URL 會反過來給您的用戶和應用程序增加很多。 您應該使用一些工具來監視 SPA 的性能,并監視所有需要的更改。
## 總結
回顧一下,我們首先通過 Java 持久化 API 構建數據庫,然后創建了 Java 資源類以作為 REST 服務訪問數據庫,盡管這里我們僅演示了 GET 方法。 在完成了后端之后,我們繼續進行前端,我們創建了 HTML 組件文件,這要歸功于 AngularJS,它非常簡單明了。 最后,Javascript 文件將所有內容組合在一起,為應用程序注入了生命。
Angular 是一個非常強大的框架,它允許您僅用幾行代碼即可創建完全不同的 UX,這非常令人驚訝。 能夠通過 Java RESTful 后端擴展 JS 前端可以增加更多的表格,并提高您作為開發人員的技能。 Angular 越來越流行,誰知道它何時會成為開發標準,與此同時,它是 SPA 領域的第一大統治框架。 請記住,傳統網頁也有其優點,因此您需要事先確定要遵循的模式。 例如,MPA 更安全,因為它們涉及的客戶端腳本更少,并且正如我們之前提到的,它們更易于針對 SEO 進行優化。 在開發中總會有這種折衷,您必須選擇一個選擇。 但是,SPA 將繼續是一個非常強大的選擇。
- JavaTutorialNetwork 中文系列教程
- Java 基礎
- Java 概述
- 在 Ubuntu 上安裝 Java 8 JDK
- Java Eclipse 教程
- Eclipse 快捷方式
- 簡單的 Java 示例
- Java 基本類型
- Java 循環
- Java 數組
- Java 讀取文件示例
- Java 對象和類教程
- 什么是面向對象編程(OOP)
- Java 封裝示例
- Java 接口示例
- Java 繼承示例
- Java 抽象示例
- Java 多態示例
- Java 中的方法重載與方法覆蓋
- Java 控制流語句
- Java 核心
- 如何在 Windows,Linux 和 Mac 上安裝 Maven
- 如何使用 Maven 配置文件
- 如何將自定義庫包含到 Maven 本地存儲庫中
- 如何使用 JUnit 進行單元測試
- 如何使用 Maven 運行 JUnit 測試
- 如何在 Java 中使用 Maven 創建子模塊
- 如何使用 Maven 創建 Java JAR 文件
- 如何使用 Maven 創建 Java WAR 文件
- JVM 解釋
- Java 內存模型解釋示例
- 捕獲 Java 堆轉儲的前 3 種方法
- Java 垃圾收集
- Java 互斥量示例
- Java 信號量示例
- Java 并行流示例
- Java 線程同步
- Java 線程池示例
- Java ThreadLocal示例
- Java 中的活鎖和死鎖
- Java Future示例
- Java equals()方法示例
- Java Lambda 表達式教程
- Java Optional示例
- Java 11 HTTP 客戶端示例
- Java 類加載器介紹
- Java 枚舉示例
- Java hashCode()方法示例
- 如何測試獨立的 Java 應用程序
- SWING JFrame基礎知識,如何創建JFrame
- Java SWING JFrame布局示例
- 在JFrame上顯示文本和圖形
- 與JFrame交互 – 按鈕,監聽器和文本區域
- 如何使用 Maven 創建 Java JAR 文件
- Java Collection新手指南
- 選擇合適的 Java 集合
- Java ArrayList示例
- Java LinkedList示例
- Java HashSet示例
- Java TreeSet示例
- Java LinkedHashSet示例
- Java EnumSet示例
- Java ConcurrentHashSet示例
- Java HashMap示例
- Java LinkedHashMap示例
- Java TreeMap示例
- Java EnumMap示例
- Java WeakHashMap示例
- Java IdentityHashMap示例
- Java SortedMap示例
- Java ConcurrentMap示例
- Java Hashtable示例
- Java 中ArrayList和LinkedList之間的區別
- Java HashMap迭代示例
- Java HashMap內聯初始化
- Java 中HashMap和TreeMap之間的區別
- Java 圖示例
- Java 深度優先搜索示例
- Java 廣度優先搜索示例
- 不同的算法時間復雜度
- Java 序列化示例
- Java 反射示例
- Java 中的弱引用
- Java 8 日期時間 API
- Java 基本正則表達式
- 使用 Java 檢索可用磁盤空間
- Java 生成 MD5 哈希和
- Java 增加內存
- Java 屬性文件示例
- 如何在 Eclipse 上安裝 Java 9 Beta
- Java 9 JShell 示例
- Java 9 不可變列表示例
- Java 9 不可變集示例
- Java 9 不可變映射示例
- Java 單例設計模式示例
- Java 代理設計模式示例
- Java 觀察者設計模式示例
- Java 工廠設計模式
- Java 構建器設計模式
- Java 比較器示例
- Java 發送電子郵件示例
- Java volatile示例
- Java Docker 和 Docker 容器簡介
- 安裝和配置 MySQL 數據庫和服務器以供 Spring 使用
- 如何在 Java 中使用 MySQL 連接器
- 如何使用 Eclipse 調試 Java
- Java EE
- 如何在 Windows 10 中設置JAVA_HOME
- JavaBeans 及其組件簡介
- 如何安裝和配置 Tomcat 8
- 如何在 Tomcat 中部署和取消部署應用程序
- 從 Eclipse 運行 Tomcat
- Java Servlet 示例
- Java Servlet POST 示例
- Servlet 請求信息示例
- Servlet 注解示例
- 使用初始化參數配置 Java Web 應用程序
- Java Servlet 文件上傳
- Java JSP 示例
- Glassfish 啟用安全管理
- 如何使用 MySQL 配置 Glassfish 4
- Java 文件上傳 REST 服務
- Glassfish 和 Jetty 的 Java WebSockets 教程
- 基于 Glassfish 表單的身份驗證示例
- 如何使用 Java EE 和 Angular 構建單頁應用程序
- Spring
- 在 Eclipse 中安裝 Spring STS
- 使用 STS 創建簡單的 Spring Web App
- Spring Web Framework 簡介
- Java Docker 和 Docker 容器簡介
- 在 Spring 中實現控制器
- Spring 中的PathVariable注解
- Spring 中的RequestBody注解
- Spring 中的RequestParam注解
- Spring 攔截器
- Spring IOC
- Java Spring IoC 容器示例
- Spring 中的DispatcherServlet
- Spring 示例中的依賴注入
- 實現 Spring MVC 控制器
- Spring ORM 簡介
- 什么是 DAO 以及如何使用它
- 如何對 DAO 組件進行單元測試
- 如何對控制器和服務執行單元測試
- 安裝和配置 MySQL 數據庫和服務器以供 Spring 使用
- 如何在 Spring 中處理登錄身份驗證
- Spring Security 簡介及其設置
- 如何使用 Spring 創建 RESTful Web 服務
- Spring CSRF 保護
- Spring 中基于 OAuth2 的身份驗證和授權
- Spring Boot 簡介
- Spring MVC 框架介紹
- Spring JDBC 簡介
- 如何 docker 化 Spring 應用程序
- Spring 的@Autowired注解
- Spring AOP 中的核心概念和建議類型
- Sping Bean 簡介
- 如何在 Java 中使用 MySQL 連接器
- 安卓
- 安裝和配置 Android Studio
- 將 Android 設備連接到 Android Studio
- Android 簡介,活動,意圖,服務,布局
- 創建一個簡單的 Android 應用
- 運行和調試 Android 應用程序
- 在虛擬設備上運行 Android 應用程序
- Android 活動示例
- Android 意圖示例
- Android 服務示例
- Android 線性布局示例
- Android 相對布局示例
- Android Web 視圖示例
- Android 列表視圖示例
- Android 網格視圖示例
- 帶有ListAdapter的 Android ListView示例
- Android SQLite 數據庫介紹
- Android SQLite 數據庫示例
- Android 動畫教程
- Android 中的通知
- Android 中的事件處理
- 如何在 Android 中發送帶有附件的電子郵件
- 雜項
- 選擇您的 JAVA IDE:Eclipse,NetBeans 和 IntelliJ IDEA
- Java S3 示例
- 如何在 Ubuntu 上為多個站點配置 Apache
- 如何在 Liferay DXP 中替代現成的(OOTB)模塊
- 簡單的 Git 教程
- 使用 Java 捕獲網絡數據包
- Selenium Java 教程
- 使用特定工作區運行 Eclipse
- 在 Eclipse 中安裝 SVN
- 如何運行 NodeJS 服務器
- SQL 內連接示例
- SQL 左連接示例
- SQL 右連接示例
- SQL 外連接示例
- 樹莓派
- Raspberry Pi 3 規格
- 將 Raspbian 安裝到 SD 卡
- Raspberry Pi 首次啟動
- 遠程連接到 Raspberry Pi
- 建立 Raspberry Pi 遠程桌面連接
- Raspberry Pi Java 教程
- 使用 PWM 的 Raspberry Pi LED 亮度調節
- Raspberry Pi 控制電機速度
- Raspberry Pi 用 Java 控制直流電機的速度和方向