摘要:現(xiàn)在可以通過點擊指標(biāo)檢查的指標(biāo),該數(shù)據(jù)是可用的格式。健康檢查被添加。現(xiàn)在啟動,可以看到第步創(chuàng)建現(xiàn)在寫類,它負(fù)責(zé)創(chuàng)建博客條目。為了測試,做一個請求第步更新現(xiàn)在,更新方法來從獲取所有的博客文件。
編者注:我們發(fā)現(xiàn)了比較有趣的系列文章《30天學(xué)習(xí)30種新技術(shù)》,準(zhǔn)備翻譯,一天一篇更新,年終禮包。下面是第十三天的內(nèi)容。
我已經(jīng)是一個使用了8年Java的軟件開發(fā)人員了,我寫過的大多數(shù)應(yīng)用程序是用的Spring框架或Java EE。最近,我花了一些時間學(xué)習(xí)用Python進行web開發(fā),其中印象非常深刻的是 Flask 框架——一個微型架構(gòu),這使得它很容易寫REST后端。所以今天我決定找一個Java的Python Flask框架替代品,做一些研究后,我發(fā)現(xiàn) Dropwizard 框架可以幫助達(dá)到Flask框架同樣的生產(chǎn)力。在這篇博客中,我們將學(xué)習(xí)如何使用Dropwizard構(gòu)建一個基于REST的Java MongoDB應(yīng)用程序。
Dropwizard 是一個開源的Java框架,用于開發(fā)OPS友好、高性能的基于REST的后端。它是由Yammer開發(fā)的,來驅(qū)動基于JVM的后端。
Dropwizard提供同類最佳的Java庫到一個嵌入式應(yīng)用程序包。它由以下部分組成:
嵌入式Jetty:每一個應(yīng)用程序被打包成一個jar(而不是war)文件,并開始自己的嵌入式Jetty容器。沒有任何war文件和外部servlet容器。
JAX-RS:Jersey(JAX-RS的參考實現(xiàn))是用來寫基于REST的Web服務(wù)的。
JSON:REST服務(wù)用的是JSON,Jackson庫用來做所有的JSON處理。
日志:使用Logback和SLF4J完成。
Hibernate驗證:Dropwizard使用Hibernate驗證API進行聲明性驗證。
指標(biāo):Dropwizard支持監(jiān)控使用標(biāo)準(zhǔn)庫,它在監(jiān)控代碼方面有無與倫比的洞察力。
除了上面提到的這幾個,Dropwizard還使用了一些其他的庫,你可以在這里找到完整的列表。
我決定學(xué)Dropwizard的原因有以下幾點:
快速的項目引導(dǎo):如果你已經(jīng)在使用Spring和Java EE,你就會明白開發(fā)人員在引導(dǎo)項目時的痛苦。使用Dropwizard,你只需要在你的 pom.xml 文件中添加一個依賴就完成了。
應(yīng)用指標(biāo):Dropwizard自帶應(yīng)用程序指標(biāo)的支持。它提供了類似請求/響應(yīng)時間這種非常有用的信息,只要把@ 定時注解來獲取方法的執(zhí)行時間。
生產(chǎn)力:每個Dropwizard應(yīng)用程序有一個啟動Jetty容器的主程序。這意味著,完全可以把應(yīng)用程序作為一個主程序在IDE中運行和調(diào)試。所以就沒有重新編譯或部署war文件。
今天的演示應(yīng)用程序的代碼在GitHub上有:day13-dropwizard-mongodb-demo-app。
必備條件基礎(chǔ)的Java知識是必須的;
下載并安裝 MongoDB數(shù)據(jù)庫;
安裝最新版本的Java Development Kit (JDK),OpenJDK 7 或是 Oracle JDK 7 都可以,這篇文章中使用JDK 7;
去Eclipse官網(wǎng)下載最新版本的Eclipse包,就目前而言eclipse最新版的代號是Kepler;
Eclipse的安裝很容易,只需要解壓下載下來的包即可。如果是在Linux或者Mac機器上,開個命令行窗口,輸入如下命令:
$ tar -xzvf eclipse-jee-kepler-R-*.tar.gz
Windows下,你解壓到哪里,那里就會有一個eclipse文件夾,這樣就可以直接操作了,當(dāng)然你也可以創(chuàng)建執(zhí)行文件的快捷方式到桌面。
打開Eclipse IDE,然后到項目工作區(qū)(project workspace)。要創(chuàng)建一個新的項目,轉(zhuǎn)到 文件>新建> Maven項目 (File > New > Maven Project) ,然后選擇 Maven 原型 - 快速啟動 (maven-archetype-quickstart),然后進入Ground Id 和 Artifact Id,最后點擊“完成”。
現(xiàn)在更新pom.xml文件以包括dropwizard核心maven依賴。同時也將更新Maven項目使用Java 1.7版本,更新pom.xml文件后,更新Maven項目(右鍵單擊>Maven>更新項目)。
第3步:創(chuàng)建配置類4.0.0 com.shekhar blog 0.0.1-SNAPSHOT jar blog http://maven.apache.org UTF-8 com.yammer.dropwizard dropwizard-core 0.6.2 org.apache.maven.plugins maven-compiler-plugin 3.1 1.7
每個Dropwizard應(yīng)用程序都有一個配置類,它指定特定的環(huán)境參數(shù)。文章后面會將如主機、端口和數(shù)據(jù)庫名之類的MongoDB的配置參數(shù)添加給它。這個類擴展了 com.yammer.dropwizard.config.Configuration類。
import com.yammer.dropwizard.config.Configuration; public class BlogConfiguration extends Configuration{ }第4步:創(chuàng)建服務(wù)類
該Dropwizard項目由一個服務(wù)類自舉。這個類將各種提供基本功能的捆綁和命令集合在一塊,它還啟動嵌入式Jetty服務(wù)器并延伸com.yammer.dropwizard.Service。
import com.yammer.dropwizard.Service; import com.yammer.dropwizard.config.Bootstrap; import com.yammer.dropwizard.config.Environment; public class BlogService extends Service{ public static void main(String[] args) throws Exception { new BlogService().run(new String[] { "server" }); } @Override public void initialize(Bootstrap bootstrap) { bootstrap.setName("blog"); } @Override public void run(BlogConfiguration configuration, Environment environment) throws Exception { } }
上面的這些服務(wù)類可以:
有一個作為服務(wù)入口點的main方法。在main方法里面,創(chuàng)建BlogService的實例,并調(diào)用run方法。我們將服務(wù)器命令作為參數(shù)傳遞,服務(wù)器命令將啟動嵌入式Jetty服務(wù)器。
初始化方法在服務(wù)運行方法之前被調(diào)用。
接下來,服務(wù)運行時將調(diào)用它的run方法,文章后面會將JAX-RS源加到這個方法里。
第5步:寫IndexResource寫一個當(dāng)GET請求指向“/” URL時會被調(diào)用的源,創(chuàng)建一個新的JAX-RS源(此資源將列出所有的博客),如下:
import java.util.Arrays; import java.util.List; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import com.yammer.metrics.annotation.Timed; @Path("/") public class IndexResource { @GET @Produces(value = MediaType.APPLICATION_JSON) @Timed public Listindex() { return Arrays.asList(new Blog("Day 12: OpenCV--Face Detection for Java Developers", "https://www.openshift.com/blogs/day-12-opencv-face-detection-for-java-developers")); } }
上面這段代碼是一個標(biāo)準(zhǔn)的JAX-RS資源類。它添加@ Path注釋和定義index()方法,這個index()會返回一個博客集合,這些博客將被轉(zhuǎn)換為JSON文檔。
上面提到IndexResource是用博客表示的。下面這段則表明該博客使用Hibernate驗證器注解,以確保內(nèi)容是有效的。例如,使用@URL注釋,以確保只有合法的URL存儲在MongoDB數(shù)據(jù)庫。
import java.util.Date; import java.util.UUID; import org.hibernate.validator.constraints.NotBlank; import org.hibernate.validator.constraints.URL; public class Blog { private String id = UUID.randomUUID().toString(); @NotBlank private String title; @URL @NotBlank private String url; private final Date publishedOn = new Date(); public Blog() { } public Blog(String title, String url) { super(); this.title = title; this.url = url; } public String getId() { return id; } public String getTitle() { return title; } public String getUrl() { return url; } public Date getPublishedOn() { return publishedOn; } }
接下來,在服務(wù)類的run方法注冊IndexResource。用下面的方式更新BlogService run方法。
@Override public void run(BlogConfiguration configuration, Environment environment) throws Exception { environment.addResource(new IndexResource()); }
現(xiàn)在,可以將BlogService類??作為一個主程序來運行(右鍵點擊>運行方式> Java應(yīng)用程序),這將啟動嵌入式Jetty容器,我們可以看到程序在 http://localhost:8080/ 里運行。
$ curl http://localhost:8080 [{"id":"9bb43d53-5436-4dac-abaa-ac530c833df1","title":"Day 12: OpenCV--Face Detection for Java Developers","url":"https://www.openshift.com/blogs/day-12-opencv-face-detection-for-java-developers","publishedOn":1384090975372}]
現(xiàn)在可以通過點擊“指標(biāo)(Metrics)”檢查IndexResource的指標(biāo),該數(shù)據(jù)是可用的JSON格式。
"com.shekhar.blog.IndexResource" : { "index" : { "type" : "timer", "duration" : { "unit" : "milliseconds", "min" : 17.764, "max" : 17.764, "mean" : 17.764, "std_dev" : 0.0, "median" : 17.764, "p75" : 17.764, "p95" : 17.764, "p98" : 17.764, "p99" : 17.764, "p999" : 17.764 }, "rate" : { "unit" : "seconds", "count" : 1, "mean" : 7.246537731991882E-4, "m1" : 2.290184897291144E-12, "m5" : 3.551918562683463E-5, "m15" : 2.445031498756583E-4 } } },第6步:配置MongoDB
在pom.xml 里加入 mongo-jackson-mapper 的依賴。
net.vz.mongodb.jackson mongo-jackson-mapper 1.4.2
用MongoDB數(shù)據(jù)庫的詳細(xì)信息(如主機、端口和數(shù)據(jù)庫名等)更新BlogConfiguration類。
import javax.validation.constraints.Max; import javax.validation.constraints.Min; import org.codehaus.jackson.annotate.JsonProperty; import org.hibernate.validator.constraints.NotEmpty; import com.yammer.dropwizard.config.Configuration; public class BlogConfiguration extends Configuration { @JsonProperty @NotEmpty public String mongohost = "localhost"; @JsonProperty @Min(1) @Max(65535) public int mongoport = 27017; @JsonProperty @NotEmpty public String mongodb = "mydb"; }
接下來,創(chuàng)建一個名為MongoManaged的新類,它將允許你在應(yīng)用程序啟動和停止時管理程序資源。這樣就實現(xiàn)了com.yammer.dropwizard.lifecycle.Managed。
import com.mongodb.Mongo; import com.yammer.dropwizard.lifecycle.Managed; public class MongoManaged implements Managed { private Mongo mongo; public MongoManaged(Mongo mongo) { this.mongo = mongo; } @Override public void start() throws Exception { } @Override public void stop() throws Exception { mongo.close(); } }
在上面的代碼中,關(guān)閉了stop方法中的MongoDB連接。
下一步,寫一個MongoHealthCheck來檢查MongoDB的連接與否。
import com.mongodb.Mongo; import com.yammer.metrics.core.HealthCheck; public class MongoHealthCheck extends HealthCheck { private Mongo mongo; protected MongoHealthCheck(Mongo mongo) { super("MongoDBHealthCheck"); this.mongo = mongo; } @Override protected Result check() throws Exception { mongo.getDatabaseNames(); return Result.healthy(); } }
現(xiàn)在,更新BlogService類??,將MongoDB的配置包含進來。
package com.shekhar.blog; import com.mongodb.Mongo; import com.yammer.dropwizard.Service; import com.yammer.dropwizard.config.Bootstrap; import com.yammer.dropwizard.config.Environment; public class BlogService extends Service{ public static void main(String[] args) throws Exception { new BlogService().run(new String[] { "server" }); } @Override public void initialize(Bootstrap bootstrap) { bootstrap.setName("blog"); } @Override public void run(BlogConfiguration configuration, Environment environment) throws Exception { Mongo mongo = new Mongo(configuration.mongohost, configuration.mongoport); MongoManaged mongoManaged = new MongoManaged(mongo); environment.manage(mongoManaged); environment.addHealthCheck(new MongoHealthCheck(mongo)); environment.addResource(new IndexResource()); } }
上面這段代碼:
使用BlogConfiguration對象創(chuàng)建了一個新的Mongo實例。
一個新的MongoManaged實例被創(chuàng)建并添加到環(huán)境中。
健康檢查被添加。
運行該應(yīng)用程序作為主程序。你可以到本地的 http://localhost:8081/healthcheck 健康檢查頁面去檢驗MongoDB是否在運行,如果MongoDB沒有運行,會看到一個異常堆棧跟蹤。
! MongoDBHealthCheck: ERROR ! can"t call something : Shekhars-MacBook-Pro.local/192.168.1.101:27017/admin com.mongodb.MongoException$Network: can"t call something : Shekhars-MacBook-Pro.local/192.168.1.101:27017/admin at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:227) at com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:305) at com.mongodb.DB.command(DB.java:160) at com.mongodb.DB.command(DB.java:183) at com.mongodb.Mongo.getDatabaseNames(Mongo.java:327) at com.shekhar.blog.MongoHealthCheck.check(MongoHealthCheck.java:17) at com.yammer.metrics.core.HealthCheck.execute(HealthCheck.java:195) at Caused by: java.io.IOException: couldn"t connect to [Shekhars-MacBook-Pro.local/192.168.1.101:27017] bc:java.net.ConnectException: Connection refused at com.mongodb.DBPort._open(DBPort.java:228) at com.mongodb.DBPort.go(DBPort.java:112) at com.mongodb.DBPort.call(DBPort.java:79) at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:218) ... 33 more * deadlocks: OK
現(xiàn)在啟動MongoDB,可以看到:
* MongoDBHealthCheck: OK * deadlocks: OK第7步:創(chuàng)建BlogResource
現(xiàn)在寫B(tài)logResource類,它負(fù)責(zé)創(chuàng)建博客條目。
import java.util.ArrayList; import java.util.List; import javax.validation.Valid; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import net.vz.mongodb.jackson.DBCursor; import net.vz.mongodb.jackson.JacksonDBCollection; import com.yammer.metrics.annotation.Timed; @Path("/blogs") @Produces(value = MediaType.APPLICATION_JSON) @Consumes(value = MediaType.APPLICATION_JSON) public class BlogResource { private JacksonDBCollectioncollection; public BlogResource(JacksonDBCollection blogs) { this.collection = blogs; } @POST @Timed public Response publishNewBlog(@Valid Blog blog) { collection.insert(blog); return Response.noContent().build(); } }
下一步,更新BlogService run方法,將BlogResource也加進來。
@Override public void run(BlogConfiguration configuration, Environment environment) throws Exception { Mongo mongo = new Mongo(configuration.mongohost, configuration.mongoport); MongoManaged mongoManaged = new MongoManaged(mongo); environment.manage(mongoManaged); environment.addHealthCheck(new MongoHealthCheck(mongo)); DB db = mongo.getDB(configuration.mongodb); JacksonDBCollectionblogs = JacksonDBCollection.wrap(db.getCollection("blogs"), Blog.class, String.class); environment.addResource(new IndexResource()); environment.addResource(new BlogResource(blogs)); }
將BlogService類作為一個Java應(yīng)用程序運行。為了測試BlogResource,做一個curl請求:
$ curl -i -X POST -H "Content-Type: application/json" -d "{"title":"Day 12: OpenCV--Face Detection for Java Developers","url":"https://www.openshift.com/blogs/day-12-opencv-face-detection-for-java-developers"}" http://localhost:8080/blogs HTTP/1.1 204 No Content Date: Sun, 10 Nov 2013 14:08:03 GMT Content-Type: application/json第8步:更新IndexResource
現(xiàn)在,更新IndexResource index()方法來從MongoDB獲取所有的博客文件。
import java.util.ArrayList; import java.util.List; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import net.vz.mongodb.jackson.DBCursor; import net.vz.mongodb.jackson.JacksonDBCollection; import com.yammer.metrics.annotation.Timed; @Path("/") public class IndexResource { private JacksonDBCollectioncollection; public IndexResource(JacksonDBCollection blogs) { this.collection = blogs; } @GET @Produces(value = MediaType.APPLICATION_JSON) @Timed public List index() { DBCursor dbCursor = collection.find(); List blogs = new ArrayList<>(); while (dbCursor.hasNext()) { Blog blog = dbCursor.next(); blogs.add(blog); } return blogs; } }
更新BlogService run方法將博客集合傳遞給IndexResource。
@Override public void run(BlogConfiguration configuration, Environment environment) throws Exception { Mongo mongo = new Mongo(configuration.mongohost, configuration.mongoport); MongoManaged mongoManaged = new MongoManaged(mongo); environment.manage(mongoManaged); environment.addHealthCheck(new MongoHealthCheck(mongo)); DB db = mongo.getDB(configuration.mongodb); JacksonDBCollectionblogs = JacksonDBCollection.wrap(db.getCollection("blogs"), Blog.class, String.class); environment.addResource(new IndexResource(blogs)); environment.addResource(new BlogResource(blogs)); }
將BlogService類作為一個Java應(yīng)用程序運行。為了測試BlogResource,做一個curl請求:
$ curl http://localhost:8080 [{"id":"527f9806300462bbd300687e","title":"Day 12: OpenCV--Face Detection for Java Developers","url":"https://www.openshift.com/blogs/day-12-opencv-face-detection-for-java-developers","publishedOn":1384093702592}]第9步:部署到云端
這里有一篇文章,教你如何在OpenShift部署Dropwizard應(yīng)用,點擊這里。
今天就這些,歡迎反饋。
原文 Day 13: Dropwizard--The Awesome Java REST Server Stack
整理 SegmentFault
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/63989.html
摘要:是當(dāng)時唯一的書,而且只有語言規(guī)范。仍然在中使用未來可能被取代,但不是現(xiàn)在。仍然是大學(xué)里教授的主要語言,并且存在于很多優(yōu)秀的庫中,比如。筆者期待積極的討論。的確存在缺陷,但這些缺陷并不妨礙它在世界上最主要的公司和系統(tǒng)內(nèi)全天候地完成工作。 【編者按】本文作者為資深碼農(nóng) Tim Spann,主要講述 Java 讓人無法抗拒的眾多優(yōu)點以及一些些缺陷。本文系國內(nèi) ITOM 管理平臺 OneAPM...
摘要:是什么是一個用編寫的開源機器學(xué)習(xí)服務(wù)器應(yīng)用,可以幫助你方便地使用搭建推薦引擎。是一個可伸縮的機器學(xué)習(xí)庫,它提供眾多聚集分類過濾算法。我為什么要關(guān)心我決定學(xué)習(xí)是因為我想使用一個可以幫助我加上機器學(xué)習(xí)功能的庫。 編者注:我們發(fā)現(xiàn)了比較有趣的系列文章《30天學(xué)習(xí)30種新技術(shù)》,準(zhǔn)備翻譯,一天一篇更新,年終禮包。下面是第四天的內(nèi)容。 今天是30天學(xué)習(xí)30種新技術(shù)的第4天。到目前為止我很享...
摘要:會警告該插件未簽名。以上命令告訴創(chuàng)建一個名為的項目,使用包。的工具使從部署應(yīng)用非常方便。域名構(gòu)成了分配給應(yīng)用的的一部分。這將為我們創(chuàng)建一個應(yīng)用容器,自動配置和。同時將創(chuàng)建一個私有的倉庫并克隆到本地。 編者注:我們發(fā)現(xiàn)了有趣的系列文章《30天學(xué)習(xí)30種新技術(shù)》,正在翻譯,一天一篇更新,年終禮包。下面是第 17 天的內(nèi)容。 今天的30天學(xué)習(xí)30種新技術(shù)挑戰(zhàn),我決定學(xué)習(xí)一下JBoss ...
摘要:譯文地址譯唯快不破應(yīng)用的個優(yōu)化步驟前端的逆襲知乎專欄原文地址時過境遷,應(yīng)用比以往任何時候都更具交互性。使用負(fù)載均衡方案我們在之前討論緩存的時候簡要提到了內(nèi)容分發(fā)網(wǎng)絡(luò)。換句話說,元素的串形訪問會削弱負(fù)載均衡器以最佳形式 歡迎關(guān)注知乎專欄 —— 前端的逆襲歡迎關(guān)注我的博客,知乎,GitHub。 譯文地址:【譯】唯快不破:Web 應(yīng)用的 13 個優(yōu)化步驟 - 前端的逆襲 - 知乎專欄原文地...
閱讀 2176·2021-09-22 10:56
閱讀 1477·2021-09-07 10:11
閱讀 1805·2019-08-30 15:54
閱讀 2296·2019-08-30 15:44
閱讀 2313·2019-08-29 12:40
閱讀 3037·2019-08-28 18:25
閱讀 1742·2019-08-26 10:24
閱讀 3191·2019-08-23 18:39