javascript
使用Spring Boot和MongoDB快速进行Web应用原型设计
回到我以前的項目之一,我被要求制作一些應急申請。 時間表緊張,范圍簡單。 內部編碼標準是PHP,因此嘗試建立經典的Java EE堆棧將是一個真正的挑戰(zhàn)。 而且,說實話,完全過大了。 那怎么辦 我趁機嘗試了Spring。 我以前使用過它,但是在舊版本中,它被隱藏在此時困擾我的門戶軟件的技術堆棧中。
我的目標是使WebOps可以簡單地放在裝有Java的服務器上并運行它。 無需擺弄數(shù)十種XML配置和內存微調。 就像java -jar application.jar一樣容易。
這是“ Spring Boot”的完美呼喚。 這個Spring項目旨在簡化開發(fā)人員的工作流程,并消除對配置和樣板代碼的負擔。
我的項目渴望的另一件事是面向文檔的數(shù)據(jù)存儲。 我的意思是,該應用程序的主要目的是提供現(xiàn)實世界紙質表格的數(shù)字版本。 那么,如果我們可以將文檔表示為文檔,那么為什么要創(chuàng)建關系混亂呢? 我之前在幾個小型項目中使用過MongoDB,因此我決定繼續(xù)使用它。
這和這篇文章有什么關系? 好吧,我將向您展示如何快速整合Web應用程序所需的所有點點滴滴。 Spring Boot將使很多事情變得相當容易,并使代碼最少。 最后,您將擁有一個JAR文件,該文件是可執(zhí)行文件,只需將其拖放到服務器上即可進行部署。 您的WebOps將為此而愛您。
假設我們將要創(chuàng)建下一個大型產品管理Web應用程序。 因為這是下一件大事,所以它需要一個大名字: Productr (這就是我是軟件工程師,而不是銷售或市場營銷的原因……)。
Productr將做令人驚奇的事情,本文將向您展示其早期階段,這些階段是:
- 提供簡單的REST界面來查詢所有可用產品
- 從MongoDB加載這些產品
- 提供生產就緒的監(jiān)控設施
- 使用JavaScript UI顯示所有產品
您需要開始的全部是:
- Java 8
- 馬文
- 您最喜歡的IDE(IntelliJ,Eclipse,vi,edlin,butterfly…)
- 瀏覽器(可以,或者是Internet Explorer / MS Edge,但是誰真的想要這個?!)
對于不耐煩的人,該代碼也可以在GitHub上獲得 。
讓我們開始吧
創(chuàng)建具有以下內容的pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.3.0.RELEASE</version></parent><modelVersion>4.0.0</modelVersion><groupId>net.h0lg.tutorials.rapid</groupId><artifactId>rapid-resting</artifactId><version>1.0</version><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build> </project>在這幾行中,已經發(fā)生了很多事情。 最重要的是已定義的父項目。 這將為我們帶來許多有用且必要的依賴項,例如日志記錄,Tomcat運行時等等。 由于Spring的模塊化,所有內容都可以通過pom.xml或依賴項注入進行重新配置。 為了快速啟動所有功能,默認設置絕對可以。 (配置公約,有人嗎?)
現(xiàn)在,創(chuàng)建強制性的Maven文件夾結構:
mkdir -p src/main/java src/main/resources src/test/java src/test/resources我們已經解決了。
啟動引擎
讓我們開始工作。 我們希望提供一個REST接口來訪問我們大量的產品。 因此,讓我們開始創(chuàng)建在/ api / products下可用的REST集合。 為此,我們必須做一些事情:
數(shù)據(jù)模型非常簡單并且可以快速完成。 只需創(chuàng)建一個名為demo.model的包和一個名為Product的類。 Product類非常簡單:
package demo.model;import java.io.Serializable;/*** Our very important and sophisticated data model*/ public class Product implements Serializable {String productId;String name;String vendor;public String getProductId() {return productId;}public void setProductId(String productId) {this.productId = productId;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getVendor() {return vendor;}public void setVendor(String vendor) {this.vendor = vendor;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Product product = (Product) o;if (getProductId() != null ? !getProductId().equals(product.getProductId()) : product.getProductId() != null)return false;if (getName() != null ? !getName().equals(product.getName()) : product.getName() != null) return false;return !(getVendor() != null ? !getVendor().equals(product.getVendor()) : product.getVendor() != null);}@Overridepublic int hashCode() {int result = getProductId() != null ? getProductId().hashCode() : 0;result = 31 * result + (getName() != null ? getName().hashCode() : 0);result = 31 * result + (getVendor() != null ? getVendor().hashCode() : 0);return result;} }我們的產品具有令人難以置信的3個屬性:字母數(shù)字產品ID,名稱和供應商(為簡單起見,僅是名稱)。 它是可序列化的,并且使用我的IDE的代碼生成來實現(xiàn)getter,setter和equals() & hashCode()方法。
好的,因此使用一種提供GET偵聽器的方法來創(chuàng)建一個控制器。 返回您最喜歡的IDE,并創(chuàng)建包demo.controller和一個名為ProductsController的類,其內容如下:
package demo.controller;import demo.model.Product; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList; import java.util.List;/*** This controller provides the REST methods*/ @RestController @RequestMapping(value = "/", method = RequestMethod.GET) public class ProductsController {@RequestMapping(value = "/", method = RequestMethod.GET)public List getProducts() {List products = new ArrayList();return products;}}這實際上是提供REST接口所需的一切。 好的,此刻返回了一個空列表,但是定義起來很簡單。
最后缺少的是我們應用程序的入口點。 只需在程序包演示中創(chuàng)建一個名為Productr的類,然后為其提供以下內容:
package demo;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;/*** This is the entry point of our application*/ @SpringBootApplication public class ProductrApplication {public static void main (String... opts) {SpringApplication.run(ProductrApplication.class, opts);}}Spring Boot為我們節(jié)省了許多按鍵操作。 無論如何,@SpringBootApplication會完成我們每個Web應用程序所需的一些操作。 該注釋是以下注釋的簡寫:
- @組態(tài)
- @EnableAutoConfiguration
- @ComponentScan
現(xiàn)在是時候第一次啟動我們的應用程序了。 借助我們在pom.xml中配置的Spring Boot的maven插件,啟動該應用程序非常簡單: mvn spring-boot:run 。 只需在項目根目錄中運行此命令即可。 您更喜歡IDE提供的惰性N鍵單擊方式? 好的,只需指示您喜歡的IDE運行ProductrApplication即可 。
一旦啟動,請使用瀏覽器,REST客戶端(您應該簽出Postman ,我喜歡這個工具)或諸如curl的命令行工具。 您要查找的地址是: http:// localhost:8080 / api / products / 。 因此,使用curl ,命令如下所示:
curl http://localhost:8080/api/products/請?zhí)峁┵Y料
好的,返回一個空列表不是很閃亮,是嗎? 因此,讓我們引入數(shù)據(jù)。 在許多項目中,經典的關系數(shù)據(jù)庫通常會顯得過大(如果必須使用它并進行橫向擴展,則會很痛苦)。 這可能是NoSQL數(shù)據(jù)庫被大肆宣傳的原因之一。 一個(在我看來很好)的例子是MongoDB。
啟動和運行MongoDB非常簡單。 在Linux上,您可以使用軟件包管理器進行安裝。 例如,對于Debian / Ubuntu,只需執(zhí)行: sudo apt-get install mongodb 。
對于Mac,最簡單的方法是自制軟件 : brew install mongodb并按照“注意事項”部分中的說明進行操作。
Windows用戶應使用MongoDB安裝程序(和toi toi toi)。
好吧,我們只是對數(shù)據(jù)存儲進行了排序。 現(xiàn)在是時候使用它了。 有一個特定的Spring項目處理數(shù)據(jù)–稱為Spring Data 。 碰巧的是,一個名為Spring Data MongoDB的子項目正等著我們。 甚至更多,Spring Boot提供了一個依賴包,可以立即加快速度。 難怪pom.xml的<dependencies>部分中的以下幾行足以引入我們需要的所有內容:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> 現(xiàn)在,創(chuàng)建一個名為demo.domain的新包,并放入一個名為ProductRepository的新接口。 Spring提供了一種非常簡潔的方法來擺脫編寫與數(shù)據(jù)源交互通常所需的代碼。 大多數(shù)基本查詢都是由Spring Data生成的-您只需要定義一個接口即可。 甚至沒有指定方法標題就可以使用幾個查詢方法。 一個示例是findAll()方法,該方法將返回集合中的所有條目。
但是,讓我們看看它在起作用,而不是在談論它。 定制的ProductRepository接口應如下所示:
接下來,在同一包中創(chuàng)建一個名為ProductService的類。 此類的目的是實際提供一些用于查詢產品的有用方法。 現(xiàn)在,代碼就像這樣簡單:
package demo.domain;import demo.model.Product; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import java.util.List;/*** This is a little service class we will let Spring inject later.*/ @Service public class ProductService {@Autowiredprivate ProductRepository repository;public List getProducts() {return repository.findAll();}}看看我們如何在沒有在接口中定義的情況下使用repository.findAll() ? 很漂亮,不是嗎? 尤其是在您急于需要快速起床的情況下。
好了,到目前為止,我們已經為數(shù)據(jù)訪問奠定了基礎。 我認為是時候將它們連接在一起了。 為此,只需回到我們的類demo.controller.ProductsController并稍加修改即可。 我們要做的就是注入我們閃亮的新ProductService服務并調用其getProducts()方法。 之后,該類將如下所示:
package demo.controller;import demo.domain.ProductService; import demo.model.Product; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList; import java.util.List;/*** This controller provides the REST methods*/ @RestController @RequestMapping("/api/products/") public class ProductsController {// Let Spring DI inject the service for us@Autowiredprivate ProductService productService;@RequestMapping(value = "/", method = RequestMethod.GET)public List getProducts() {// Ask the data store for a list of productsreturn productService.getProducts();}}而已。 啟動MongoDB(如果尚未運行),再次啟動我們的應用程序(還記得mvn spring-boot:run whaty ?!),并向http:// localhost:8080 / api / products /發(fā)起另一個GET請求:
$ curl http://localhost:8080/api/products/ []等等,還是一個空名單? 是的,或者您還記得我們將任何內容放入數(shù)據(jù)庫嗎? 讓我們使用以下命令來更改它:
mongo localhost/test --eval "db.product.insert({productId: 'a1234', name: 'Our First Product', vendor: 'ACME'})"這會將一個名為“我們的第一個產品”的產品添加到我們的數(shù)據(jù)庫中。 好的,我們的服務現(xiàn)在返回什么? 這個:
$ curl http://localhost:8080/api/products/ [{"productId":"5657654426ed9d921affc3c0","name":"Our First Product","vendor":"ACME"}]很簡單,不是嗎?
尋找更多數(shù)據(jù)卻沒有時間自己創(chuàng)建? 好了,快到圣誕節(jié)了,所以請選擇我的一些小測試:
curl https://gist.githubusercontent.com/daincredibleholg/f8667a26ce2f17776903/raw/ed9b4c8ec6c9c455dc063e833af2418648928ba6/quick-web-app-product-example.json | mongoimport -d test -c product --jsonArray基本要求唾手可得
在當今繁忙的日子里,隨著“微服務”文化的傳播,關注服務器或云環(huán)境上實際運行的內容變得越來越困難。 因此,在過去幾年中,我在幾乎所有環(huán)境中進行監(jiān)控都是一件大事。 一種常見的模式是提供運行狀況檢查端點。 從簡單的ping端點到運行狀況指標,您可以找到所有內容,并返回與業(yè)務相關的指標的詳細概述。 所有這些在大多數(shù)情況下都是“復制粘貼”冒險,涉及處理許多樣板代碼。 這是我們要做的–只需將以下依賴項添加到pom.xml中:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>并重新啟動服務。 讓我們看看如果查詢http:// localhost:8080 / health會發(fā)生什么:
$ curl http://localhost:8080/health {"status":"UP","diskSpace":{"status":"UP","total":499088621568,"free":83261571072,"threshold":10485760},"mongo":{"status":"UP","version":"3.0.7"}}這應該為基本的健康檢查提供足夠的數(shù)據(jù)。 如果遵循啟動日志消息,則可能會發(fā)現(xiàn)許多其他端點。 嘗試一下,然后查看執(zhí)行器文檔以獲取更多信息。
給我看看
好的,我們獲得了REST服務和一些數(shù)據(jù)。 但是我們想將這些數(shù)據(jù)顯示給我們的用戶。 因此,讓我們繼續(xù)并提供一個頁面,其中概述了我們的出色產品。
感謝圣誕老人,這里有一個非?;钴S的Web UI社區(qū),致力于處理漂亮,易用的前端框架和庫。 一個很受歡迎的例子是Bootstrap 。 它易于使用,并且所有所需的點點滴滴都通過開放的CDN提供。
我們希望對我們的產品有一個簡短的概述,所以表格視圖會很不錯。 Bootstrap Table將幫助我們實現(xiàn)這一目標。 它建立在Bootstrap之上,也可以通過CDN使用。 我們生活在一個怎樣的世界里……
但是,等等,將我們HTML文件放在哪里? Spring Boot再次使它變得容易。 只需創(chuàng)建一個名為src / main / resources / static的文件夾,并創(chuàng)建一個具有以下內容的名為index.html的新HTML文件:
<!DOCTYPE html> <html> <head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Productr</title><!-- Import Bootstrap CSS from CDNs --><link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.9.1/bootstrap-table.min.css"> </head> <body> <nav class="navbar navbar-inverse"><div class="container"><div class="navbar-header"><button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a class="navbar-brand" href="#">Productr</a></div><div id="navbar" class="collapse navbar-collapse"><ul class="nav navbar-nav"><li class="active"><a href="#">Home</a></li><li><a href="#about">About</a></li><li><a href="#contact">Contact</a></li></ul></div><!--/.nav-collapse --></div> </nav><div class="container"><table data-toggle="table" data-url="/api/products/"><thead><tr><th data-field="productId">Product Reference</th><th data-field="name">Name</th><th data-field="vendor">Vendor</th></tr></thead></table></div><!-- Import Bootstrap, Bootstrap Table and JQuery JS from CDNs --><script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script><script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script><script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.9.1/bootstrap-table.min.js"></script> </body> </html>這個文件不是很復雜。 它只是一個HTML文件,其中包括CDN中最小化CSS文件。 如果您第一次看到類似//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css之類的引用,那么協(xié)議(http或https)丟失就是一個不錯的錯誤。 以這種方式引用的資源將通過與加載主頁相同的協(xié)議進行加載。 說,如果您使用http:// localhost:8080 / ,它將使用http:加載CSS文件。
<body>塊包含一個導航欄(使用HTML5 <nav>標記)和一個表。 該表定義的有趣部分是提供的data-url屬性。 Bootstrap表將其解釋為加載數(shù)據(jù)。 我們的定義指向我們先前創(chuàng)建的REST端點。 通過<th>定義上的data-field屬性定義在哪一列中使用JSON對象的哪一部分。 您可以找到匹配的屬性名稱嗎?
最后但并非最不重要的一點是,我們加載了所需JavaScript庫。 所有與Bootstrap相關JavaScript功能都需要JQuery,因此這是第一個要加載的庫。 緊隨其后的是主要的Bootstrap和Bootstrap Table JavaScript文件。 這些庫文件中的每個文件均以最小化版本加載,以使下載時間保持最少。
現(xiàn)在去哪里
可以說我們現(xiàn)在有一個非常簡單的Web應用程序。 好吧,本文的主要目的是向您展示如何以盡可能少的代碼來加快速度。 您已經看到,有時POM文件中的依賴項為您帶來了一項全新的功能,而無需任何其他代碼。 退后一步,看看到目前為止我們已經建立了什么,然后考慮下一步需要做的事情。 并開始在Spring宇宙中四處看看。
我認為,除了添加缺少的測試之外,接下來需要的最關鍵的步驟之一就是引入安全性。 查看Spring Security及其子項目Spring Security OAuth 。 對“經典”網頁更感興趣? 查看Spring MVC以及集成非常復雜的模板引擎有多么容易(例如,通過遵循本指南 )。
希望您喜歡這篇文章,也喜歡我喜歡它的創(chuàng)作。 祝大家圣誕快樂,如果一個或另一個想要與您取得聯(lián)系,您可以在Twitter , G +和LinkedIn上找到我。
翻譯自: https://www.javacodegeeks.com/2015/12/quick-web-app-prototyping-spring-boot-mongodb.html
總結
以上是生活随笔為你收集整理的使用Spring Boot和MongoDB快速进行Web应用原型设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: javafx_JavaFX 2 Game
- 下一篇: 国内油价中秋国庆前或将大涨!涨幅正逼近0