1. 概述
Dropwizard 是一個開源 Java 框架,用於快速開發高性能的 RESTful Web 服務。它彙集了一些流行的庫,以創建輕量級軟件包。它主要使用 Jetty、Jersey、Jackson、JUnit 和 Guava 等庫。此外,它還使用自己的庫 Metrics。
在本教程中,我們將學習如何配置和運行一個簡單的 Dropwizard 應用程序。完成之後,我們的應用程序將暴露一個 RESTful API,允許我們獲取存儲的品牌列表。
2. Maven 依賴項
首先,dropwizard-core 依賴項就足以創建我們的服務。 讓我們將其添加到我們的 pom.xml 中:
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-core</artifactId>
<version>2.0.0</version>
</dependency>
3. 配置
現在,我們將創建每個 Dropwizard 應用程序運行所需的類。
Dropwizard 應用程序使用 YML 文件存儲屬性。因此,我們將創建位於資源目錄下的 introduction-config.yml 文件:
defaultSize: 5
我們可以通過創建擴展 io.dropwizard.Configuration 的類來訪問這些值:
public class BasicConfiguration extends Configuration {
@NotNull private final int defaultSize;
@JsonCreator
public BasicConfiguration(@JsonProperty("defaultSize") int defaultSize) {
this.defaultSize = defaultSize;
}
public int getDefaultSize() {
return defaultSize;
}
}
Dropwizard 使用 Jackson 將配置文件反序列化為我們的類。因此,我們使用了 Jackson 的註解。
接下來,讓我們創建一個負責準備服務以供使用的主應用程序類:
public class IntroductionApplication extends Application<BasicConfiguration> {
public static void main(String[] args) throws Exception {
new IntroductionApplication().run("server", "introduction-config.yml");
}
@Override
public void run(BasicConfiguration basicConfiguration, Environment environment) {
//register classes
}
@Override
public void initialize(Bootstrap<BasicConfiguration> bootstrap) {
bootstrap.setConfigurationSourceProvider(new ResourceConfigurationSourceProvider());
super.initialize(bootstrap);
}
}
首先,main 方法負責運行應用程序。我們可以通過傳遞 args 到 run 方法或自行填充它。
第一個參數可以是 server 或 check。 check 選項驗證配置,而 server 選項運行應用程序。第二個參數是配置文件的位置。
此外,initialize 方法將配置提供程序設置為 ResourceConfigurationSourceProvider,這允許應用程序在資源目錄中找到給定的配置文件。不強制覆蓋此方法。
最後,run 方法允許我們訪問 Environment 和 BaseConfiguration,我們將稍後在本文中使用它們。
4. 資源
首先,我們創建一個品牌領域的類:
public class Brand {
private final Long id;
private final String name;
// all args constructor and getters
}
其次,我們創建一個 BrandRepository 類,該類將負責返回品牌:
public class BrandRepository {
private final List<Brand> brands;
public BrandRepository(List<Brand> brands) {
this.brands = ImmutableList.copyOf(brands);
}
public List<Brand> findAll(int size) {
return brands.stream()
.limit(size)
.collect(Collectors.toList());
}
public Optional<Brand> findById(Long id) {
return brands.stream()
.filter(brand -> brand.getId().equals(id))
.findFirst();
}
}
此外,我們能夠使用 ImmutableList 從 Guava,因為它是 Dropwizard 的一部分。
第三,我們將創建一個 BrandResource 類。Dropwizard 默認使用 JAX-RS,Jersey 作為實現。因此,我們將使用該規範中的註解來公開我們的 REST API 端點:
@Path("/brands")
@Produces(MediaType.APPLICATION_JSON)
public class BrandResource {
private final int defaultSize;
private final BrandRepository brandRepository;
public BrandResource(int defaultSize, BrandRepository brandRepository) {
this.defaultSize = defaultSize;
this.brandRepository = brandRepository;
}
@GET
public List<Brand> getBrands(@QueryParam("size") Optional<Integer> size) {
return brandRepository.findAll(size.orElse(defaultSize));
}
@GET
@Path("/{id}")
public Brand getById(@PathParam("id") Long id) {
return brandRepository
.findById(id)
.orElseThrow(RuntimeException::new);
}
}
此外,size 定義為 Optional,以便在參數未提供的情況下使用 defaultSize 來自我們的配置。
最後,我們將 BrandResource 註冊到 IntroductionApplicaton 類中。為了做到這一點,讓我們實現 run 方法:
@Override
public void run(BasicConfiguration basicConfiguration, Environment environment) {
int defaultSize = basicConfiguration.getDefaultSize();
BrandRepository brandRepository = new BrandRepository(initBrands());
BrandResource brandResource = new BrandResource(defaultSize, brandRepository);
environment
.jersey()
.register(brandResource);
}
所有創建的資源都應在其中註冊的方法中註冊。
5. 運行應用程序
在本節中,我們將學習如何從命令行運行應用程序。
首先,我們將配置項目以使用 maven-shade-plugin 構建 JAR 文件:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<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.baeldung.dropwizard.introduction.IntroductionApplication</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
這是插件的建議配置。 此外,我們還包括了主類路徑在 <mainClass> 元素中。
最後,我們將使用 Maven 構建應用程序。 獲得 JAR 文件後,我們可以運行應用程序:
java -jar target/dropwizard-0.0.1-SNAPSHOT.jar
因為我們已經在 <IntroductionApplication 類> 中包含了參數,所以不需要傳遞參數。
之後,控制枱日誌應該以以下內容結尾:
INFO [2020-01-08 18:55:06,527] org.eclipse.jetty.server.Server: Started @1672ms
現在,應用程序正在監聽端口 8080,我們可以通過 <http://localhost:8080/brands> 訪問我們的品牌端點。
6. 修改默認端口
默認情況下,典型的 Dropwizard 應用程序使用兩個端口:
- 端口 8080 用於主應用程序
- 端口 8081 用於管理界面
但是,我們可以使用配置文件夾或命令行參數來更改默認端口。
6.1. 通過配置文件的修改端口
要通過配置文件更改默認端口,我們需要修改資源目錄中的 introduction-config.yml:
server:
applicationConnectors:
- type: http
port: 9090
adminConnectors:
- type: http
port: 9091
此配置將應用程序設置為在端口 9090 和管理界面在端口 9091 上運行。我們可以通過將配置文件的傳遞給 run() 方法來應用此配置:
// ...
new IntroductionApplication().run("server", "introduction-config.yml");
// ...
此外,我們可以在啓動應用程序時通過命令行應用配置文件的內容:
$ java -jar target/dropwizard-0.0.1-SNAPSHOT.jar server introduction-config.yml
在上面的命令中,我們使用 server 和 introduction-config.yml 參數啓動應用程序。
6.2. 通過命令行修改端口
或者,我們可以使用命令行上的 JVM 系統屬性來覆蓋端口設置:
$ java -Ddw.server.applicationConnectors[0].port=9090 \
-Ddw.server.adminConnectors[0].port=9091 \
-jar target/dropwizard-0.0.1-SNAPSHOT.jar server
前綴 -Ddw 定義了 Dropwizard 特定系統屬性,這些屬性設置主應用程序端口和管理界面端口。如果定義了這些系統屬性,則會覆蓋配置文件的設置。如果在未定義系統屬性的情況下,則使用配置文件的值。
7. 健康檢查
啓動應用程序時,我們得知該應用程序沒有健康檢查。 幸運的是,com.codahale.metrics.health.HealthCheck 的簡單類:
public class ApplicationHealthCheck extends HealthCheck {
@Override
protected Result check() throws Exception {
return Result.healthy();
}
}
這個簡單的方法將返回有關我們組件健康狀況的信息。 我們可以創建多個健康檢查,有些檢查在某些情況下可能會失敗。 例如,如果數據庫連接失敗,我們將返回 Result.unhealthy()。
最後,我們需要在 IntroductionApplication 類的 run 方法中 註冊我們的健康檢查:
environment
.healthChecks()
.register("application", new ApplicationHealthCheck());
運行應用程序後,我們可以通過 http://localhost:8081/healthcheck 檢查健康檢查響應:
{
"application": {
"healthy": true,
"duration": 0
},
"deadlocks": {
"healthy": true,
"duration": 0
}
}
正如我們所看到的,我們的健康檢查已註冊在 application 標籤下。
8. 結論
在本文中,我們學習瞭如何使用 Maven 設置 Dropwizard 應用程序。
我們發現應用程序的基礎設置非常簡單快捷。 此外,Dropwizard 包含了我們運行高性能 RESTful Web 服務的每個庫。