javascript
Web应用程序体系结构– Spring MVC – AngularJs堆栈
Spring MVC和AngularJs共同為構建表單密集型Web應用程序提供了一個真正高效且吸引人的前端開發堆棧。在這篇博客文章中,我們將看到如何使用這些技術構建表單密集型Web應用程序,并將這種方法與其他方法進行比較可用選項。 可以在此github 存儲庫中找到功能完整且受保護的示例Spring MVC / AngularJs Web應用程序。我們將研究以下主題:
- Spring MVC + Angular單頁應用程序的體系結構
- 如何使用Angular構建Web UI
- 哪個Javascript / CSS庫與Angular相輔相成?
- 如何使用Spring MVC構建REST API后端
- 使用Spring Security保護REST API
- 與使用完全基于Java的方法的其他方法相比,這又如何呢?
Spring MVC + Angular單頁Web應用程序的體系結構
表單密集型企業級應用程序非常適合構建為單頁Web應用程序。 與其他更傳統的服務器端體系結構相比,主要思想是將服務器構建為一組無狀態可重用的REST服務,并從MVC的角度將控制器從后端移出并移至瀏覽器中:
客戶端具有MVC功能,并包含在視圖層,控制器層和前端服務層中分隔的所有表示邏輯。 初始應用程序啟動后,只有JSON數據通過客戶端和服務器之間的連接。
后端是如何構建的?
企業前端應用程序的后端可以以非常自然和類似于Web的方式構建為REST API。 可以使用相同的技術為第三方應用程序提供Web服務-在許多情況下,不需要單獨的SOAP Web服務堆棧。
從DDD的角度來看,域模型保留在服務和持久層級別的后端。 通過有線只有DTO可以通過,而域模型則不可以。
如何使用Angular構建Web應用程序的前端
前端應圍繞特定于視圖的模型(不是域模型)構建,并且應僅處理表示邏輯,而不能處理業務邏輯。 這些是前端的三層:
視圖層
視圖層由HTML模板,CSS和代表不同UI組件的任何Angular指令組成。 這是登錄表單的簡單視圖示例:
<form ng-submit="onLogin()" name="form" novalidate="" ng-controller="LoginCtrl"> <fieldset><legend>Log In</legend><div class="form-field"><input ng-model="vm.username" name="username" required="" ng-minlength="6" type="text"><div class="form-field"><input ng-model="vm.password" name="password" required="" ng-minlength="6" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}" type="password"></div></div></fieldset><button type="submit">Log In</button><a href="/resources/public/new-user.html">New user?</a></form>控制器層
控制器層由Angular控制器組成,它們將從后端和視圖檢索的數據粘合在一起。 控制器初始化視圖模型,并定義視圖應如何對模型更改做出反應,反之亦然:
angular.module('loginApp', ['common', 'editableTableWidgets']) .controller('LoginCtrl', function ($scope, LoginService) {$scope.onLogin = function () {console.log('Attempting login with username ' + $scope.vm.username + ' and password ' + $scope.vm.password);if ($scope.form.$invalid) {return;}LoginService.login($scope.vm.userName, $scope.vm.password);};});控制器的主要職責之一是執行前端驗證。 在前端進行的任何驗證僅出于方便用戶的目的-例如,它們對于立即通知用戶必填字段很有用。
由于安全原因,任何前端驗證都需要在后端在服務層級別重復進行,因為可以輕松繞過前端驗證。
前端服務層
一組允許與后端交互并可以注入到Angular控制器中的Angular服務:
angular.module('frontendServices', []) .service('UserService', ['$http','$q', function($http, $q) {return {getUserInfo: function() {var deferred = $q.defer();$http.get('/user').then(function (response) {if (response.status == 200) {deferred.resolve(response.data);}else {deferred.reject('Error retrieving user info');}});return deferred.promise;}讓我們看看還需要哪些其他庫來啟動前端并運行它。
哪些Javascript / CSS庫是補充Angular所必需的?
Angular已經提供了構建應用程序前端所需的大部分功能。 Angular的一些很好的補充是:
- 雅虎僅有4k的一個易于主題化的純CSS庫,名為PureCss 。 它的皮膚生成器可以輕松地基于基色生成主題。 它的BYOJ(自帶Java腳本)解決方案有助于使事情保持“成角度的方式”。
- 功能性的程序庫來處理數據。 這些年來,似乎最常用,維護和記錄最完善的工具就是lodash 。
使用這兩個庫和Angular, 幾乎可以構建任何基于表單的應用程序 ,實際上不需要任何其他操作。 根據您的項目,其他一些庫可能是一個選項:
- 像requirejs這樣的模塊系統很不錯,但是由于Angular模塊系統不處理文件檢索,因此在requirejs和angular模塊的依賴項聲明之間引入了一些重復。
- CSRF Angular模塊,用于防止跨站點請求偽造攻擊。
- 國際化模塊
如何使用Spring MVC構建REST API后端
后端是使用通常的后端層構建的:
- 路由器層:定義哪些服務入口點對應于給定的HTTP URL,以及如何從HTTP請求中讀取參數
- 服務層:包含任何業務邏輯(例如驗證),定義業務交易的范圍
- 持久層:將數據庫映射到內存中的域對象或從中映射
目前,最好僅使用Java配置來配置Spring MVC。 幾乎不需要web.xml ,請參閱此處的僅使用Java config的完全配置的應用程序示例。
服務和持久層是使用通常的DDD方法構建的,因此讓我們將注意力集中在路由器層上。
路由器層
用于構建JSP / Thymeleaf應用程序的相同Spring MVC批注也可以用于構建REST API。
最大的區別在于,控制器方法不返回定義應渲染哪個視圖模板的String。 相反,
@ResponseBody批注指示應該直接呈現controller方法的返回值并成為響應主體:
如果要使用@ResponseBody注釋該類的所有方法,則最好使用@RestController注釋整個類。
通過添加Jackson JSON庫,方法返回值將直接轉換為JSON,而無需任何進一步配置。 也可以轉換為XML或其他格式,具體取決于客戶端指定的Accept HTTP標頭的值。
請參見此處的幾個配置了錯誤處理的控制器的示例。
如何使用Spring Security保護REST API
可以使用Spring Security Java配置來保護REST API。 一個好的方法是使用帶有回退到HTTP Basic身份驗證的表單登錄,并包括一些CSRF保護,以及強制所有后端方法只能通過HTTPS訪問的可能性。
這意味著后端將為用戶提供一個登錄表單,并在成功登錄到瀏覽器客戶端時分配一個會話cookie,但是通過支持回退到HTTP Basic(通過憑據通過Authorization HTTP標頭傳遞憑據)的非瀏覽器客戶端,它仍然可以很好地工作。 。
遵循OWASP的建議,可以使REST服務達到最小的無狀態(唯一的服務器狀態是用于身份驗證的會話cookie),以避免必須為每個請求通過電線發送憑據。
這是有關如何配置REST API安全性的示例 :
http.authorizeRequests().antMatchers("/resources/public/**").permitAll().anyRequest().authenticated().and().formLogin().defaultSuccessUrl("/resources/calories-tracker.html").loginProcessingUrl("/authenticate").loginPage("/resources/public/login.html").and().httpBasic().and().logout().logoutUrl("/logout");if ("true".equals(System.getProperty("httpsOnly"))) {LOGGER.info("launching the application in HTTPS-only mode");http.requiresChannel().anyRequest().requiresSecure();}此配置僅涵蓋安全性的身份驗證方面,選擇授權策略取決于API的安全性要求。 如果您需要對授權進行非常細粒度的控制,請檢查Spring Security ACL是否適合您的用例。
現在,讓我們看一下這種構建Web應用程序的方法與其他常用方法的比較。
將Spring / MVC Angular堆棧與其他常見方法進行比較
這種將Javascript用作前端,將Java用作后端的方法可以簡化開發工作流程。
當后端運行時,不需要任何特殊工具或插件即可實現完整的前端熱部署功能:只需使用您的IDE將資源發布到服務器即可(例如, Ctrl+F10 IntelliJ中的Ctrl+F10 )并刷新瀏覽器頁面。
仍然可以使用JRebel重新加載后端類,但是對于前端而言 ,不需要任何特殊的操作。 實際上,可以通過使用json-server模擬后端來構建整個前端。 如果需要,這將允許不同的開發人員并行構建前端和后端。
全棧開發的生產力收益?
根據我的經驗,能夠直接編輯Html和CSS,而無需中間的任何間接層(請參閱此處, 與GWT和JSF進行的高級Angular比較 )有助于減少工作量并使事情簡單。 編輯保存刷新開發周期非常快速且可靠,極大地提高了生產率。
當相同的開發人員同時構建Javascript前端和Java后端時,將獲得最大的生產率提高,因為大多數功能通常都需要同時更改兩者。
這樣做的潛在缺點是,開發人員還需要了解Html,CSS和Javascript,但這在最近幾年中變得越來越常見。
根據我的經驗,與等效的完整Java解決方案相比,使用全棧可以在很短的時間內實現復雜的前端用例(用幾天而不是幾周的時間),因此提高生產率使學習曲線絕對值得。
結論
Spring MVC和Angular的結合確實為構建表單密集型Web應用程序的新方法打開了大門。 這種方法所帶來的生產率提高使其成為值得研究的替代方案。
請求之間不存在任何服務器狀態(除了身份驗證cookie),通過設計消除了整個類別的錯誤。
有關更多詳細信息,請查看github上的該示例應用程序 ,并讓我們知道您對以下注釋的想法/問題。
翻譯自: https://www.javacodegeeks.com/2015/01/web-app-architecture-the-spring-mvc-angularjs-stack.html
總結
以上是生活随笔為你收集整理的Web应用程序体系结构– Spring MVC – AngularJs堆栈的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用系统规则测试System.in和Sy
- 下一篇: gradle idea java ssm