Dropwizard官方教程(一) 入門

入門

本文將指導(dǎo)您完成一個(gè)簡單的Dropwizard的Hello World項(xiàng)目怠褐。在此過程中,我們將解釋各種底層庫及其作用雏门,以及Dropwizard中的重要概念鼎姐,并建議一些組織技術(shù)來幫助您的項(xiàng)目能持續(xù)健康地增長。

概覽

Dropwizard跨越了作為lib庫和框架之間的界限船殉。其目標(biāo)是為生產(chǎn)就緒的Web應(yīng)用程序所需的所有內(nèi)容提供高性能鲫趁,高可靠的實(shí)現(xiàn)。并且這些功能被封裝到可重用的庫中利虫,因此您的應(yīng)用程序仍然很精簡和專注挨厚,從而縮短了產(chǎn)品上線時(shí)間和維護(hù)負(fù)擔(dān)。

用于HTTP的Jetty

因?yàn)槟腤eb應(yīng)用程序不能沒有HTTP糠惫,Dropwizard使用Jetty 疫剃,一個(gè)令人難以置信的調(diào)優(yōu)HTTP服務(wù)器直接嵌入到您的項(xiàng)目中。Dropwizard項(xiàng)目沒有將應(yīng)用程序交給復(fù)雜的應(yīng)用程序服務(wù)器硼讽,而是有一個(gè)main方法運(yùn)行HTTP服務(wù)器巢价。將您的應(yīng)用程序作為一個(gè)簡單的過程運(yùn)行,消除了生產(chǎn)中Java的許多令人討厭的方面(沒有PermGen問題,沒有應(yīng)用程序服務(wù)器配置和維護(hù)蹄溉,沒有神秘的部署工具,沒有類加載器問題您炉,沒有隱藏的應(yīng)用程序日志柒爵,沒有嘗試調(diào)整單個(gè)垃圾收集器與多個(gè)應(yīng)用程序工作負(fù)載一起工作)并允許您使用所有現(xiàn)有的Unix進(jìn)程管理工具。

用于REST的Jersey

為了構(gòu)建RESTful Web應(yīng)用程序赚爵,我們發(fā)現(xiàn)在功能或性能方面沒有任何東西勝過JerseyJAX-RS參考實(shí)現(xiàn))棉胀。它允許您編寫干凈,可測試的類冀膝,這些類可以優(yōu)雅地將HTTP請求映射到簡單的Java對象唁奢。它支持流輸出,矩陣URI參數(shù)窝剖,條件GET請求等等麻掸。

用于JSON的Jackson

在數(shù)據(jù)格式方面,JSON已成為網(wǎng)絡(luò)的通用語言赐纱,而Jackson則是JVM上的JSON之王脊奋。除了快速閃電之外,它還有一個(gè)復(fù)雜的對象映射器疙描,允許您直接導(dǎo)出域模型诚隙。

用于監(jiān)控的Metrics

指標(biāo)有助于分析問題,為您提供無與倫比的洞悉您的生產(chǎn)環(huán)境中的代碼的行為起胰。

其他集成的工具

除了Jetty久又,JerseyJackson之外,Dropwizard還包括一些庫效五,可以幫助您更快速高效地開發(fā)地消。

  • Guava除了高度優(yōu)化的不可變數(shù)據(jù)結(jié)構(gòu)外,還提供了越來越多的類來加速Java的開發(fā)畏妖。
  • Logbackslf4j用于高性能和靈活的日志記錄犯建。
  • Hibernate ValidatorJSR 349參考實(shí)現(xiàn),它提供了一個(gè)簡單的聲明性框架瓜客,用于驗(yàn)證用戶輸入并生成有用且易于i18n的錯(cuò)誤消息适瓦。
  • Apache的HttpClient的Jersey客戶端庫允許都與其他Web服務(wù)低收入和高層次的互動(dòng)。
  • JDBI是使用Java的關(guān)系數(shù)據(jù)庫最直接的方法谱仪。
  • Liquibase是在整個(gè)開發(fā)和發(fā)布周期中檢查數(shù)據(jù)庫模式的好方法玻熙,應(yīng)用高級數(shù)據(jù)庫重構(gòu)而不是一次性DDL腳本。
  • FreemarkerMustache是簡單的模板系統(tǒng)疯攒,適用于面向用戶的更多應(yīng)用程序嗦随。
  • Joda Time是一個(gè)非常完整,理智的庫,用于處理日期和時(shí)間枚尼。

既然你已經(jīng)了解到這了贴浙,那就讓我們深入挖掘吧!

使用Maven進(jìn)行設(shè)置

我們建議您將Maven用于新的Dropwizard應(yīng)用程序署恍。如果你是一個(gè)大型的Ant / Ivy崎溃,BuildrGradle盯质,SBT袁串,LeiningenGant粉絲,這很酷呼巷,但我們使用Maven囱修,我們將在使用Maven時(shí)通過這個(gè)示例應(yīng)用程序。如果您對Maven如何運(yùn)作有任何疑問王悍, Maven:The Complete Reference應(yīng)該有你想要的東西破镰。

你有三種選擇:

  1. 使用dropwizard-archetype創(chuàng)建項(xiàng)目:

    mvn archetype:generate -DarchetypeGroupId=io.dropwizard.archetypes -DarchetypeArtifactId=java-simple -DarchetypeVersion=[REPLACE WITH A VALID DROPWIZARD VERSION]
    
  2. 看一下dropwizard-example

  3. 請按照以下教程了解如何將其包含在現(xiàn)有項(xiàng)目中

教程

首先,dropwizard.version使用當(dāng)前版本的Dropwizard(1.3.5)向POM 添加屬性:

<properties>
    <dropwizard.version>INSERT VERSION HERE</dropwizard.version>
</properties>

dropwizard-core庫添加為依賴項(xiàng):

<dependencies>
    <dependency>
        <groupId>io.dropwizard</groupId>
        <artifactId>dropwizard-core</artifactId>
        <version>${dropwizard.version}</version>
    </dependency>
</dependencies>

很好压储,這些足夠了啤咽。我們現(xiàn)在已經(jīng)建立了一個(gè)Maven項(xiàng)目,現(xiàn)在是時(shí)候開始編寫真正的代碼了渠脉。

創(chuàng)建配置類

每個(gè)Dropwizard應(yīng)用程序都有自己的Configuration類的子類宇整,它指定特定的環(huán)境參數(shù)。這些參數(shù)在YAML配置文件中指定芋膘,該文件被反序列化為應(yīng)用程序配置類的實(shí)例鳞青。

我們將要構(gòu)建的應(yīng)用程序是一個(gè)高性能的Hello World服務(wù)。我們需要至少指定兩件事:一個(gè)用于說出問候的模板和一個(gè)默認(rèn)名稱为朋,以防用戶未指定其名稱臂拓。

這是我們的配置類的樣子,這里有完整的示例

package com.example.helloworld;

import io.dropwizard.Configuration;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.hibernate.validator.constraints.NotEmpty;

public class HelloWorldConfiguration extends Configuration {
    @NotEmpty
    private String template;

    @NotEmpty
    private String defaultName = "Stranger";

    @JsonProperty
    public String getTemplate() {
        return template;
    }

    @JsonProperty
    public void setTemplate(String template) {
        this.template = template;
    }

    @JsonProperty
    public String getDefaultName() {
        return defaultName;
    }

    @JsonProperty
    public void setDefaultName(String name) {
        this.defaultName = name;
    }
}

這里有很多知識點(diǎn)习寸,所以讓我們解釋一下吧胶惰。

當(dāng)從YAML文件反序列化該類時(shí),它將從YAML對象中提取兩個(gè)根級別字段:template霞溪,我們的Hello World說明的模板孵滞,以及defaultName要使用的默認(rèn)名稱。templatedefaultName都標(biāo)注了@NotEmpty鸯匹,所以如果YAML配置文件有任何空值或缺少template完全的信息會拋出異常坊饶,并且應(yīng)用程序?qū)o法啟動(dòng)。

templatedefaultName的getter和setter都有注釋 @JsonProperty殴蓬,這允許Jackson既可以從YAML文件反序列化屬性匿级,也可以序列化它。

注意

從YAML到您的應(yīng)用程序Configuration實(shí)例的映射由Jackson完成。這意味著您的Configuration類可以使用Jackson的所有對象映射注釋痘绎。驗(yàn)證@NotEmpty由Hibernate Validator處理藤违,它具有 廣泛的內(nèi)置約束供您使用搓茬。

我們的YAML文件將如下所示消痛,完整的示例yml在這里

template: Hello, %s!
defaultName: Stranger

Dropwizard有許多比這更多的配置參數(shù)倒彰,但他們都有健全的默認(rèn)值涂身,這樣可以保持你的配置文件小消别,重點(diǎn)突出不傅。

因此若锁,將YAML文件保存在您計(jì)劃運(yùn)行的jar的目錄中(見下文)hello-world.yml凌净,因?yàn)槲覀兒芸炀蜁?dòng)并運(yùn)行悲龟,我們將需要它。接下來冰寻,我們正在創(chuàng)建我們的應(yīng)用程序類须教!

創(chuàng)建應(yīng)用程序類

結(jié)合項(xiàng)目的Configuration子類,Application子類構(gòu)成了Dropwizard應(yīng)用程序的核心斩芭。所述Application類啟動(dòng)各bundle和command命令轻腺,其提供基本功能在一起(稍后會詳細(xì)介紹)。但是現(xiàn)在划乖,我們 HelloWorldApplication看起來像這樣:

package com.example.helloworld;

import io.dropwizard.Application;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import com.example.helloworld.resources.HelloWorldResource;
import com.example.helloworld.health.TemplateHealthCheck;

public class HelloWorldApplication extends Application<HelloWorldConfiguration> {
    public static void main(String[] args) throws Exception {
        new HelloWorldApplication().run(args);
    }

    @Override
    public String getName() {
        return "hello-world";
    }

    @Override
    public void initialize(Bootstrap<HelloWorldConfiguration> bootstrap) {
        // nothing to do yet
    }

    @Override
    public void run(HelloWorldConfiguration configuration,
                    Environment environment) {
        // nothing to do yet
    }

}

如您所見贬养,HelloWorldApplication使用應(yīng)用程序的配置類型HelloWorldConfiguration進(jìn)行參數(shù)化。initialize方法用于在運(yùn)行應(yīng)用程序之前配置所需應(yīng)用程序的各個(gè)方面琴庵,如bundle误算,配置源提供程序等。此外迷殿,我們還添加了一個(gè)static main方法儿礼,它將成為我們應(yīng)用程序的入口點(diǎn)。現(xiàn)在庆寺,我們沒有實(shí)現(xiàn)任何功能蚊夫,所以我們的run方法有點(diǎn)無聊。讓我們解決這個(gè)問題懦尝!

創(chuàng)建表示類

在我們進(jìn)入Hello World應(yīng)用程序的細(xì)節(jié)之前知纷,我們需要停下來思考一下我們的API。幸運(yùn)的是陵霉,我們的應(yīng)用程序需要符合行業(yè)標(biāo)準(zhǔn)RFC 1149屈扎,它規(guī)定了Hello World的以下JSON表示:

{
  "id": 1,
  "content": "Hi!"
}

id字段是該問候的唯一標(biāo)識符,并且content是該問候的文本表示撩匕。(值得慶幸的是鹰晨,這是一個(gè)相當(dāng)直接的行業(yè)標(biāo)準(zhǔn)。)

要對此表示進(jìn)行建模,我們將創(chuàng)建一個(gè)表示類:

package com.example.helloworld.api;

import com.fasterxml.jackson.annotation.JsonProperty;
import org.hibernate.validator.constraints.Length;

public class Saying {
    private long id;

    @Length(max = 3)
    private String content;

    public Saying() {
        // Jackson deserialization
    }

    public Saying(long id, String content) {
        this.id = id;
        this.content = content;
    }

    @JsonProperty
    public long getId() {
        return id;
    }

    @JsonProperty
    public String getContent() {
        return content;
    }
}

這是一個(gè)非常簡單的POJO模蜡,但有一些值得注意的事情漠趁。

首先,它是不可改變的忍疾。這使得Saying實(shí)例在多線程環(huán)境以及單線程環(huán)境中非常容易推理闯传。其次,它使用JavaBeans標(biāo)準(zhǔn)idcontent屬性卤妒。這允許Jackson將其序列化為我們需要的JSON甥绿。Jackson對象映射代碼將id使用返回值填充JSON對象的字段#getId(),同樣使用content#getContent()则披。最后共缕,bean利用驗(yàn)證來確保內(nèi)容大小不超過3。

注意

這里的JSON序列化由Jackson完成士复,它支持的不僅僅是像這樣的簡單JavaBean對象图谷。除了復(fù)雜的注釋集,您甚至可以編寫自定義序列化程序和反序列化程序阱洪。

既然我們已經(jīng)有了表示類便贵,接下來學(xué)習(xí)下資源。

創(chuàng)建資源類

Jersey資源是Dropwizard應(yīng)用程序的核心冗荸。每個(gè)資源類都與URI模板相關(guān)聯(lián)承璃。對于我們的應(yīng)用程序,我們需要從URI /hello-world返回一個(gè)Saying 實(shí)例蚌本,因此我們的資源類如下所示:

package com.example.helloworld.resources;

import com.example.helloworld.api.Saying;
import com.codahale.metrics.annotation.Timed;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.util.concurrent.atomic.AtomicLong;
import java.util.Optional;

@Path("/hello-world")
@Produces(MediaType.APPLICATION_JSON)
public class HelloWorldResource {
    private final String template;
    private final String defaultName;
    private final AtomicLong counter;

    public HelloWorldResource(String template, String defaultName) {
        this.template = template;
        this.defaultName = defaultName;
        this.counter = new AtomicLong();
    }

    @GET
    @Timed
    public Saying sayHello(@QueryParam("name") Optional<String> name) {
        final String value = String.format(template, name.orElse(defaultName));
        return new Saying(counter.incrementAndGet(), value);
    }
}

HelloWorldResource有兩個(gè)注釋:@Path@Produces绸硕。@Path("/hello-world") 告訴Jersey,這個(gè)資源可以在URI上訪問/hello-world魂毁,并且 @Produces(MediaType.APPLICATION_JSON)讓Jersey的內(nèi)容協(xié)商代碼知道這個(gè)資源產(chǎn)生的表示形式是application/json玻佩。

HelloWorldResource采用兩個(gè)參數(shù)進(jìn)行構(gòu)造:template它用于產(chǎn)生問候語,當(dāng)用戶拒絕告訴我們他們的名字時(shí)使用defaultName席楚。AtomicLong為我們提供了一種廉價(jià)咬崔,線程安全的方法來生成唯一(ish)ID。

警告

資源類由多個(gè)線程同時(shí)使用烦秩。一般來說垮斯,我們建議資源是無狀態(tài)/不可變的,但重要的是要記住上下文只祠。

#sayHello(Optional<String>)是這個(gè)類的核心兜蠕,這是一個(gè)相當(dāng)簡單的方法。@QueryParam("name")注解告訴Jersey從請求參數(shù)字符串中把name參數(shù)賦值給方法中的name參數(shù)抛寝。如果客戶端發(fā)送請求 /hello-world?name=Dougie熊杨,sayHello將被調(diào)用Optional.of("Dougie"); 如果name查詢字符串中沒有參數(shù)曙旭,sayHello則將調(diào)用Optional.absent()。(支持Guava的Optional是Dropwizard為Jersey的現(xiàn)有功能添加的一些額外的功能)

注意

如果客戶端發(fā)送請求/hello-world?name=晶府,sayHello將被調(diào)用 Optional.of("")桂躏。這可能看起來很奇怪,但這遵循標(biāo)準(zhǔn)(應(yīng)用程序可能具有不同的行為川陆,具體取決于參數(shù)是否為空而不存在)剂习。如果你希望/hello-world?name=返回“Hello,Stranger较沪!”鳞绕,可以用NonEmptyStringParam替換 Optional<String>參數(shù)。有關(guān)資源參數(shù)的更多信息尸曼,請參閱 文檔

sayHello方法內(nèi)部们何,我們遞增計(jì)數(shù)器,使用格式化模板String.format(String,Object...) 骡苞,并返回一個(gè)Saying新實(shí)例垂蜗。

因?yàn)?code>sayHello帶有注釋@Timed楷扬,Dropwizard會自動(dòng)將其調(diào)用的持續(xù)時(shí)間和速率記錄為Metrics Timer解幽。

一旦sayHello返回,Jersey就會獲取Saying實(shí)例并查找可以將Saying實(shí)例寫為application/json的轉(zhuǎn)換類烘苹。Dropwizard內(nèi)置了一個(gè)這樣的轉(zhuǎn)換類躲株,允許使用Java對象生成JSON對象,JSON對象生成Java對象镣衡。該轉(zhuǎn)換類生成JSON霜定,客戶端會收到200 OK 的內(nèi)容類型為application/json的響應(yīng)。

注冊資源

不過廊鸥,在這一切生效之前望浩,我們需要回到HelloWorldApplication并注冊這個(gè)新的資源類。在run方法中惰说,我們可以從HelloWorldConfiguration實(shí)例中讀取模板和默認(rèn)名稱 磨德,創(chuàng)建一個(gè)新HelloWorldResource實(shí)例,然后將其添加到應(yīng)用程序的Jersey環(huán)境中:

@Override
public void run(HelloWorldConfiguration configuration,
                Environment environment) {
    final HelloWorldResource resource = new HelloWorldResource(
        configuration.getTemplate(),
        configuration.getDefaultName()
    );
    environment.jersey().register(resource);
}

當(dāng)我們的應(yīng)用程序啟動(dòng)時(shí)吆视,我們使用配置文件中的參數(shù)創(chuàng)建一個(gè)新的資源類實(shí)例典挑,并將其交給它Environment,它就像應(yīng)用程序可以執(zhí)行的所有操作的注冊表啦吧。

注意

Dropwizard應(yīng)用程序可以包含許多資源類您觉,每個(gè)資源類都對應(yīng)于自己的URI。只需添加另一個(gè)@Path注釋資源類授滓,并使用新類的實(shí)例調(diào)用register方法即可琳水。

在我們走得太遠(yuǎn)之前肆糕,我們應(yīng)該為我們的應(yīng)用添加健康檢查。

創(chuàng)建健康檢查

運(yùn)行狀況檢查為您提供了一種向應(yīng)用程序添加小測試的方法炫刷,以便您驗(yàn)證應(yīng)用程序在生產(chǎn)中是否正常運(yùn)行擎宝。我們強(qiáng)烈建議您的所有應(yīng)用程序至少具有一組最小的運(yùn)行狀況檢查。

注意

事實(shí)上浑玛,我們強(qiáng)烈推薦這一點(diǎn)绍申,如果你忽略了為你的項(xiàng)目添加健康檢查,Dropwizard會嘮叨你顾彰。

由于格式化字符串在應(yīng)用程序運(yùn)行時(shí)不太可能失敿摹(與數(shù)據(jù)庫連接池不同),因此我們必須在這里想一些創(chuàng)意涨享。我們將添加一個(gè)運(yùn)行狀況檢查筋搏,以確保我們可以格式化提供的模板:

package com.example.helloworld.health;

import com.codahale.metrics.health.HealthCheck;

public class TemplateHealthCheck extends HealthCheck {
    private final String template;

    public TemplateHealthCheck(String template) {
        this.template = template;
    }

    @Override
    protected Result check() throws Exception {
        final String saying = String.format(template, "TEST");
        if (!saying.contains("TEST")) {
            return Result.unhealthy("template doesn't include a name");
        }
        return Result.healthy();
    }
}

TemplateHealthCheck 檢查兩件事:提供的模板確實(shí)是格式良好的格式字符串,模板確實(shí)能生成具有給定名稱的輸出厕隧。

如果字符串不是格式良好的格式字符串(例如奔脐,有人意外地將Hello,%s%放入 配置文件中),那么String.format(String, Object...)將拋出一個(gè)IllegalFormatException 吁讨,并且運(yùn)行狀況檢查將隱式失敗髓迎。如果呈現(xiàn)的問候語不包括測試字符串,則運(yùn)行狀況檢查將通過返回不健康的Result而顯式失敗建丧。

添加健康檢查

與Dropwizard中的大多數(shù)內(nèi)容一樣排龄,我們使用適當(dāng)?shù)膮?shù)創(chuàng)建一個(gè)新實(shí)例并將其添加到Environment

@Override
public void run(HelloWorldConfiguration configuration,
                Environment environment) {
    final HelloWorldResource resource = new HelloWorldResource(
        configuration.getTemplate(),
        configuration.getDefaultName()
    );
    final TemplateHealthCheck healthCheck =
        new TemplateHealthCheck(configuration.getTemplate());
    environment.healthChecks().register("template", healthCheck);
    environment.jersey().register(resource);
}

現(xiàn)在我們快要準(zhǔn)備好了!

建立工程的JAR包

我們建議把Dropwizard應(yīng)用程序構(gòu)建為“單” JAR文件-一個(gè).jar包含所有的運(yùn)行應(yīng)用程序所需的.class文件翎朱。這允許您構(gòu)建單個(gè)可部署工件橄维,您可以將其從開發(fā)環(huán)境升級到測試環(huán)境再到生產(chǎn)環(huán)境,而無需擔(dān)心已安裝庫中的差異拴曲。要開始構(gòu)建我們的Hello World應(yīng)用程序作為單JAR争舞,我們需要配置一個(gè)名為maven-shade的Maven插件。在文件的<build><plugins>部分中pom.xml澈灼,添加以下內(nèi)容:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.3</version>
    <configuration>
        <createDependencyReducedPom>true</createDependencyReducedPom>
        <filters>
            <filter>
                <artifact>*:*</artifact>
                <excludes>
                    <exclude>META-INF/*.SF</exclude>
                    <exclude>META-INF/*.DSA</exclude>
                    <exclude>META-INF/*.RSA</exclude>
                </excludes>
            </filter>
        </filters>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>com.example.helloworld.HelloWorldApplication</mainClass>
                    </transformer>
                </transformers>
            </configuration>
        </execution>
    </executions>
</plugin>

這將配置Maven在其package階段執(zhí)行以下操作:

  • 生成一個(gè)pom.xml文件竞川,該文件不包含在單JAR中的庫的依賴項(xiàng)的內(nèi)容。
  • 從已簽名的JAR中排除所有數(shù)字簽名蕉汪。如果不這樣做流译,則Java認(rèn)為簽名無效,并且不會加載或運(yùn)行您的JAR文件者疤。
  • 整理JAR中META-INF/services的各種條目而不是覆蓋它們福澡。(如果沒有那些,那么Dropwizard和Jersey都不會工作)
  • com.example.helloworld.HelloWorldApplication設(shè)為JAR MainClass驹马。這將允許您使用java -jar運(yùn)行JAR 革砸。

警告

如果您的應(yīng)用程序具有必須簽名的依賴項(xiàng)(例如除秀,JCA / JCE提供程序或其他可信庫),則必須在 該庫的maven-shade-plugin配置中添加排除項(xiàng)算利,并將該JAR包含在類路徑中册踩。

警告

由于Dropwizard使用Java ServiceLoader功能來注冊和加載擴(kuò)展,因此maven-shade-plugin的minimizeJar選項(xiàng)將導(dǎo)致應(yīng)用程序JAR不能正常工作效拭。

版本化您的JAR

Dropwizard也可以使用項(xiàng)目版本暂吉,如果它嵌入在JAR的清單中作為 Implementation-Version。要使用Maven嵌入此信息缎患,請將以下內(nèi)容添加到文件的 <build><plugins>部分pom.xml

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <archive>
            <manifest>
                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
            </manifest>
        </archive>
    </configuration>
</plugin>

在嘗試確定您在計(jì)算機(jī)上部署的應(yīng)用程序版本時(shí)慕的,這非常方便。

完成配置后挤渔,進(jìn)入項(xiàng)目目錄并運(yùn)行mvn package(或從IDE 運(yùn)行package 目標(biāo))肮街。你應(yīng)該看到這樣的東西:

[INFO] Including org.eclipse.jetty:jetty-util:jar:7.6.0.RC0 in the shaded jar.
[INFO] Including com.google.guava:guava:jar:10.0.1 in the shaded jar.
[INFO] Including com.google.code.findbugs:jsr305:jar:1.3.9 in the shaded jar.
[INFO] Including org.hibernate:hibernate-validator:jar:4.2.0.Final in the shaded jar.
[INFO] Including javax.validation:validation-api:jar:1.0.0.GA in the shaded jar.
[INFO] Including org.yaml:snakeyaml:jar:1.9 in the shaded jar.
[INFO] Replacing original artifact with shaded artifact.
[INFO] Replacing /Users/yourname/Projects/hello-world/target/hello-world-0.0.1-SNAPSHOT.jar with /Users/yourname/Projects/hello-world/target/hello-world-0.0.1-SNAPSHOT-shaded.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.415s
[INFO] Finished at: Fri Dec 02 16:26:42 PST 2011
[INFO] Final Memory: 11M/81M
[INFO] ------------------------------------------------------------------------

恭喜!你已經(jīng)建立了你的第一個(gè)Dropwizard項(xiàng)目判导!現(xiàn)在是時(shí)候運(yùn)行了嫉父!

運(yùn)行您的應(yīng)用程序

現(xiàn)在您已經(jīng)構(gòu)建了一個(gè)JAR文件,現(xiàn)在是時(shí)候運(yùn)行它了眼刃。

在項(xiàng)目目錄中绕辖,運(yùn)行以下命令:

java -jar target/hello-world-0.0.1-SNAPSHOT.jar

您應(yīng)該看到如下內(nèi)容:

usage: java -jar hello-world-0.0.1-SNAPSHOT.jar
       [-h] [-v] {server} ...

positional arguments:
  {server}               available commands

optional arguments:
  -h, --help             show this help message and exit
  -v, --version          show the service version and exit

Dropwizard接受第一個(gè)命令行參數(shù)并將其分派給匹配的命令。在這種情況下鸟整,唯一可用的命令是server引镊,將您的應(yīng)用程序作為HTTP服務(wù)器運(yùn)行朦蕴。該 server命令需要一個(gè)配置文件篮条,所以讓我們繼續(xù)為它提供 我們之前保存的YAML文件

java -jar target/hello-world-0.0.1-SNAPSHOT.jar server hello-world.yml

您應(yīng)該看到如下內(nèi)容:

INFO  [2011-12-03 00:38:32,927] io.dropwizard.cli.ServerCommand: Starting hello-world
INFO  [2011-12-03 00:38:32,931] org.eclipse.jetty.server.Server: jetty-7.x.y-SNAPSHOT
INFO  [2011-12-03 00:38:32,936] org.eclipse.jetty.server.handler.ContextHandler: started o.e.j.s.ServletContextHandler{/,null}
INFO  [2011-12-03 00:38:32,999] com.sun.jersey.server.impl.application.WebApplicationImpl: Initiating Jersey application, version 'Jersey: 1.10 11/02/2011 03:53 PM'
INFO  [2011-12-03 00:38:33,041] io.dropwizard.setup.Environment:

    GET     /hello-world (com.example.helloworld.resources.HelloWorldResource)

INFO  [2011-12-03 00:38:33,215] org.eclipse.jetty.server.handler.ContextHandler: started o.e.j.s.ServletContextHandler{/,null}
INFO  [2011-12-03 00:38:33,235] org.eclipse.jetty.server.AbstractConnector: Started BlockingChannelConnector@0.0.0.0:8080 STARTING
INFO  [2011-12-03 00:38:33,238] org.eclipse.jetty.server.AbstractConnector: Started SocketConnector@0.0.0.0:8081 STARTING

您的Dropwizard應(yīng)用程序現(xiàn)在正在偵聽8080應(yīng)用程序請求和8081 管理請求的端口。如果按^C吩抓,應(yīng)用程序?qū)⒄jP(guān)閉涉茧,首先關(guān)閉服務(wù)器套接字,然后等待處理正在進(jìn)行的請求疹娶,然后關(guān)閉進(jìn)程本身伴栓。

大功告成,試一下雨饺! http://localhost:8080/hello-world

我們正在產(chǎn)生問候語钳垮,真棒。當(dāng)然你的應(yīng)用程序能做到的遠(yuǎn)遠(yuǎn)不止這些额港。使用Dropwizard的主要原因之一是它提供的開箱即用的操作工具饺窿,所有這些工具都可以在管理端口上 http://localhost:8081/找到。

如果訪問指標(biāo)資源 http://localhost:8081/metrics移斩,則可以看到所有應(yīng)用程序的指標(biāo)都表示為JSON對象肚医。

訪問線程的資源 http://localhost:8081/threads可以讓您快速獲得在這個(gè)過程中運(yùn)行的所有線程的線程轉(zhuǎn)儲绢馍。

提示

當(dāng)Jetty工作線程處理傳入的HTTP請求時(shí),線程名稱將設(shè)置為請求的方法和URI肠套。在調(diào)試性能不佳的請求時(shí)舰涌,這非常有用。

健康檢查資源運(yùn)行 健康檢查類你稚。你應(yīng)該看到這樣的東西:

* deadlocks: OK
* template: OK

template這是你的TemplateHealthCheck的結(jié)果瓷耙,毫不奇怪地通過了。 deadlocks是一個(gè)內(nèi)置的運(yùn)行狀況檢查刁赖,它查找死鎖的JVM線程并打印出列表(如果找到)哺徊。

下一步

嗯,恭喜乾闰。您已經(jīng)準(zhǔn)備好用于生產(chǎn)的Hello World應(yīng)用程序(除了缺少測試)落追,它能夠每秒執(zhí)行30,000-50,000個(gè)請求。希望您已經(jīng)了解了Dropwizard如何將Jetty涯肩,Jersey轿钠,Jackson和其他穩(wěn)定,成熟的庫結(jié)合起來病苗,為開發(fā)RESTful Web應(yīng)用程序提供了一個(gè)非凡的平臺疗垛。

Dropwizard還有很多內(nèi)容(命令commands,綁定bundles硫朦,servlet贷腕,高級配置,驗(yàn)證validation咬展,HTTP客戶端泽裳,數(shù)據(jù)庫客戶端,視圖等)破婆,所有這些都在用戶手冊中介紹涮总。

官網(wǎng) https://www.dropwizard.io/1.3.5/docs/getting-started.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市祷舀,隨后出現(xiàn)的幾起案子瀑梗,更是在濱河造成了極大的恐慌,老刑警劉巖裳扯,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抛丽,死亡現(xiàn)場離奇詭異,居然都是意外死亡饰豺,警方通過查閱死者的電腦和手機(jī)亿鲜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來哟忍,“玉大人狡门,你說我怎么就攤上這事陷寝。” “怎么了其馏?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵凤跑,是天一觀的道長。 經(jīng)常有香客問我叛复,道長仔引,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任褐奥,我火速辦了婚禮咖耘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘撬码。我一直安慰自己儿倒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布呜笑。 她就那樣靜靜地躺著夫否,像睡著了一般。 火紅的嫁衣襯著肌膚如雪叫胁。 梳的紋絲不亂的頭發(fā)上凰慈,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天,我揣著相機(jī)與錄音驼鹅,去河邊找鬼微谓。 笑死,一個(gè)胖子當(dāng)著我的面吹牛输钩,可吹牛的內(nèi)容都是我干的豺型。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼张足,長吁一口氣:“原來是場噩夢啊……” “哼触创!你這毒婦竟也來了坎藐?” 一聲冷哼從身側(cè)響起为牍,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎岩馍,沒想到半個(gè)月后碉咆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蛀恩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年疫铜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片双谆。...
    茶點(diǎn)故事閱讀 39,773評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡壳咕,死狀恐怖席揽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情谓厘,我是刑警寧澤幌羞,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站竟稳,受9級特大地震影響属桦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜他爸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一聂宾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧诊笤,春花似錦系谐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至许赃,卻和暖如春止喷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背混聊。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工弹谁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人句喜。 一個(gè)月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓预愤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親咳胃。 傳聞我的和親對象是個(gè)殘疾皇子植康,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,807評論 6 342
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)展懈,斷路器销睁,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • 原文鏈接:http://www.dropwizard.io/1.2.0/docs/getting-started....
    Lance_Xu閱讀 902評論 0 0
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,095評論 25 707
  • 生活中充滿隱喻来惧,處處都有提示冗栗。得法眼者能見,通易道者能知,心靈者偶爾感應(yīng)隅居。青青翠竹钠至,盡是法身,郁郁黃花胎源,無非般若棕洋。
    婚姻與命運(yùn)閱讀 438評論 0 0