this article is copied from Day 13: Dropwizard -- The Awesome Java REST Server Stack
Setting Up Maven
% mvn archetype:create -DgroupId=com.example -DartifactId=myblog % cd myblog
% git init % git add . % git commit -m 'initial commit'
create .gitignore:
.idea/ *.iml target/
% git add .gitignore % git commit -m 'add .gitignore'
Updating the pom.xml
update pom.xml:
diff --git a/pom.xml b/pom.xml
index 2ff8c7f..0e4df99 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,6 +12,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <dropwizard.version>0.7.1</dropwizard.version>
</properties>
<dependencies>
@@ -21,5 +22,49 @@
<version>3.8.1</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>io.dropwizard</groupId>
+ <artifactId>dropwizard-core</artifactId>
+ <version>${dropwizard.version}</version>
+ </dependency>
</dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>1.6</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.myblog.MyBlogApplication</mainClass>
+ </transformer>
+ </transformers>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
</project>
install dependency
% mvn clean install
% git add pom.xml % git commit -m 'add dropwizard.version, dependency and maven-shade plugins'
Creating Configuration class
create src/main/java/com/example/myblog/MyBlogConfiguration.java:
package com.example.myblog; import io.dropwizard.Configuration; public class MyBlogConfiguration extends Configuration { }
% git add src/main/java/com/example/myblog/MyBlogConfiguration.java % git commit -m 'create configuration class'
※ name, template が必須?
Creating Application class
create src/main/java/com/example/myblog/MyBlogApplication.java:
package com.example.myblog; import io.dropwizard.Application; import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment; public class MyBlogApplication extends Application<MyBlogConfiguration> { public static void main(String[] args) throws Exception { new MyBlogApplication().run(args); } @Override public String getName() { return "my-blog"; } @Override public void initialize(Bootstrap<MyBlogConfiguration> bootstrap) { // nothing to do yet } @Override public void run(MyBlogConfiguration configuration, Environment environment) throws Exception { // nothing to do yet } }
% git add src/main/java/com/example/myblog/MyBlogApplication.java % git commit -m 'create application class'
Creating A Representation Class
create src/main/java/com/example/myblog/core/Blog.java:
package com.example.myblog.core; 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; } }
% git add src/main/java/com/example/myblog/core/Blog.java % git commit -m 'create representation class'
Creating Resource class
create src/main/java/com/example/myblog/resources/IndexResource.java:
package com.example.myblog.resources; 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.codahale.metrics.annotation.Timed; import com.example.myblog.core.Blog; @Path("/") public class IndexResource { @GET @Produces(value = MediaType.APPLICATION_JSON) @Timed public List<Blog> index() { return Arrays.asList(new Blog("getting started dropwizard 0.7.0", "http://okamuuu.hatenablog.com/entry/2014/11/06/192836")); } }
and update MyBlogApplication.java:
diff --git a/src/main/java/com/example/myblog/MyBlogApplication.java b/src/main/java/com/example/myblog/MyBlogApplication.java
index f64d82d..81c8ab4 100644
--- a/src/main/java/com/example/myblog/MyBlogApplication.java
+++ b/src/main/java/com/example/myblog/MyBlogApplication.java
@@ -4,6 +4,8 @@ import io.dropwizard.Application;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
+import com.example.myblog.resources.IndexResource;
+
public class MyBlogApplication extends Application<MyBlogConfiguration> {
public static void main(String[] args) throws Exception {
new MyBlogApplication().run(args);
@@ -22,7 +24,9 @@ public class MyBlogApplication extends Application<MyBlogConfiguration> {
@Override
public void run(MyBlogConfiguration configuration,
Environment environment) throws Exception {
- // nothing to do yet
+
+ final IndexResource indexResource = new IndexResource();
+ environment.jersey().register(indexResource);
}
}
% git add src/main/java/com/example/myblog/MyBlogApplication.java % git add src/main/java/com/example/myblog/resources/IndexResource.java % git commit -m 'add IndexResource'
Running Application
% mvn package
run it.
% java -jar target/myblog-1.0-SNAPSHOT.jar server
check it.
% curl http://localhost:8080 [{"id":"083541a0-29bc-474a-b1ec-dae598bbafc1","title":"getting started dropwizard 0.7.0","url":"http://okamuuu.hatenablog.com/entry/2014/11/06/192836","publishedOn":1416107023288}]
Configuring MongoDB
update pom.xml
diff --git a/pom.xml b/pom.xml
index 0e4df99..ed89c53 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,6 +27,11 @@
<artifactId>dropwizard-core</artifactId>
<version>${dropwizard.version}</version>
</dependency>
+ <dependency>
+ <groupId>net.vz.mongodb.jackson</groupId>
+ <artifactId>mongo-jackson-mapper</artifactId>
+ <version>1.4.2</version>
+ </dependency>
</dependencies>
<build>
% git add pom.xml % git commit -m 'add mongo-jackson-mapper to dependency'
% mvn clean install
create myblog.yml
mongoHost: localhost mongoPort: 27017 mongoDb: myblog
update src/main/java/com/example/myblog/MyBlogConfiguration.java:
package com.example.myblog; import io.dropwizard.Configuration; import com.fasterxml.jackson.annotation.JsonProperty; import org.hibernate.validator.constraints.NotEmpty; import javax.validation.constraints.Max; import javax.validation.constraints.Min; public class MyBlogConfiguration extends Configuration { @JsonProperty @NotEmpty private String mongoHost = "localhost"; @JsonProperty @Min(1) @Max(65535) private int mongoPort = 27017; @JsonProperty @NotEmpty private String mongoDb = "myblog"; @JsonProperty public String getMongoHost() { return mongoHost; } @JsonProperty public void setMongoHost(String host) { this.mongoHost = host; } @JsonProperty public int getMongoPort() { return mongoPort; } @JsonProperty public void setMongoPort(int port) { this.mongoPort = port; } @JsonProperty public String getMongoDb() { return mongoDb; } @JsonProperty public void setMongoDb(String db) { this.mongoDb = db; } }
% git add myblog.yml % git add src/main/java/com/example/myblog/MyBlogConfiguration.java % git commit -m 'add mongoDB configuration'
create src/main/java/com/example/myblog/MongoManaged.java:
package com.example.myblog; import com.mongodb.Mongo; import io.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(); } }
update src/main/java/com/example/myblog/MyBlogApplication.java
diff --git a/src/main/java/com/example/myblog/MyBlogApplication.java b/src/main/java/com/example/myblog/MyBlogApplication.java
index 81c8ab4..ce938eb 100644
--- a/src/main/java/com/example/myblog/MyBlogApplication.java
+++ b/src/main/java/com/example/myblog/MyBlogApplication.java
@@ -6,6 +6,8 @@ import io.dropwizard.setup.Environment;
import com.example.myblog.resources.IndexResource;
+import com.mongodb.Mongo;
+
public class MyBlogApplication extends Application<MyBlogConfiguration> {
public static void main(String[] args) throws Exception {
new MyBlogApplication().run(args);
@@ -25,6 +27,10 @@ public class MyBlogApplication extends Application<MyBlogConfiguration> {
public void run(MyBlogConfiguration configuration,
Environment environment) throws Exception {
+ Mongo mongo = new Mongo(configuration.getMongoHost(), configuration.getMongoPort());
+ MongoManaged mongoManaged = new MongoManaged(mongo);
+ environment.lifecycle().manage(mongoManaged);
+
final IndexResource indexResource = new IndexResource();
environment.jersey().register(indexResource);
}
% git add src/main/java/com/example/myblog/MyBlogApplication.java % git add src/main/java/com/example/myblog/MongoManaged.java % git commit -m 'add Mongo lifecycle managed class'
% mvn celan install
Add HealthCheck
create src/main/java/com/example/myblog/health/MongoHealthCheck.java
package com.example.myblog.health; import com.mongodb.Mongo; import com.codahale.metrics.health.HealthCheck; public class MongoHealthCheck extends HealthCheck { private final Mongo mongo; public MongoHealthCheck(Mongo mongo) { this.mongo = mongo; } @Override protected Result check() throws Exception { mongo.getDatabaseNames(); return Result.healthy(); } }
update src/main/java/com/example/myblog/MyBlogApplication.java:
diff --git a/src/main/java/com/example/myblog/MyBlogApplication.java b/src/main/java/com/example/myblog/MyBlogApplication.java
index 81c8ab4..902ff86 100644
--- a/src/main/java/com/example/myblog/MyBlogApplication.java
+++ b/src/main/java/com/example/myblog/MyBlogApplication.java
@@ -5,6 +5,9 @@ import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import com.example.myblog.resources.IndexResource;
+import com.example.myblog.health.MongoHealthCheck;
+
+import com.mongodb.Mongo;
public class MyBlogApplication extends Application<MyBlogConfiguration> {
public static void main(String[] args) throws Exception {
@@ -25,6 +28,14 @@ public class MyBlogApplication extends Application<MyBlogConfiguration> {
public void run(MyBlogConfiguration configuration,
Environment environment) throws Exception {
+ Mongo mongo = new Mongo(configuration.getMongoHost(), configuration.getMongoPort());
+ MongoManaged mongoManaged = new MongoManaged(mongo);
+ environment.lifecycle().manage(mongoManaged);
+
+ final MongoHealthCheck mongoHealthCheck =
+ new MongoHealthCheck(mongo);
+ environment.healthChecks().register("mongo", mongoHealthCheck);
+
final IndexResource indexResource = new IndexResource();
environment.jersey().register(indexResource);
}
% git add src/main/java/com/example/myblog/MyBlogApplication.java % git add src/main/java/com/example/myblog/health/MongoHealthCheck.java % git commit -m 'add MongoHealthCheck'
check
% java -jar target/myblog-1.0-SNAPSHOT.jar server myblog.yml
% curl http://localhost:8081/healthcheck
{"deadlocks":{"healthy":true},"mongo":{"healthy":true}
Create BlogResource
update src/main/java/com/example/myblog/core/Blog.java
package com.example.myblog.core; import java.util.Date; import net.vz.mongodb.jackson.Id; import net.vz.mongodb.jackson.ObjectId; import org.hibernate.validator.constraints.NotBlank; import org.hibernate.validator.constraints.URL; import com.fasterxml.jackson.annotation.JsonCreator; public class Blog { @Id public String id; @NotBlank public String title; @URL @NotBlank public String url; public final Date publishedOn = new Date(); }
update src/main/java/com/example/myblog/resources/IndexResource.java:
package com.example.myblog.resources; import java.util.ArrayList; import java.util.List; import com.example.myblog.core.Blog; import com.google.common.base.Optional; 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 net.vz.mongodb.jackson.DBCursor; import net.vz.mongodb.jackson.JacksonDBCollection; @Path("/") @Produces(MediaType.APPLICATION_JSON) public class IndexResource { private JacksonDBCollection<Blog, String> collection; public IndexResource(JacksonDBCollection<Blog, String> blogs) { this.collection = blogs; } @GET @Timed public List<Blog> index() { DBCursor<Blog> dbCursor = collection.find(); List<Blog> blogs = new ArrayList<Blog>(); while (dbCursor.hasNext()) { Blog blog = dbCursor.next(); blogs.add(blog); } return blogs; } }
create src/main/java/com/example/myblog/resources/BlogResource.java:
package com.example.myblog.resources; 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.example.myblog.core.Blog; import com.codahale.metrics.annotation.Timed; @Path("/blogs") @Produces(value = MediaType.APPLICATION_JSON) @Consumes(value = MediaType.APPLICATION_JSON) public class BlogResource { private JacksonDBCollection<Blog, String> collection; public BlogResource(JacksonDBCollection<Blog, String> blogs) { this.collection = blogs; } @GET @Timed public List<Blog> blogsTimeLine() { DBCursor<Blog> dbCursor = collection.find(); List<Blog> blogs = new ArrayList<Blog>(); while (dbCursor.hasNext()) { Blog blog = dbCursor.next(); blogs.add(blog); } return blogs; } @POST @Timed public Response publishNewBlog(@Valid Blog blog) { collection.insert(blog); return Response.noContent().build(); } }
update src/main/java/com/example/myblog/MyBlogApplication.java:
package com.example.myblog; import io.dropwizard.Application; import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment; import com.example.myblog.core.Blog; import com.example.myblog.resources.IndexResource; import com.example.myblog.resources.BlogResource; import com.example.myblog.health.MongoHealthCheck; import com.mongodb.Mongo; import com.mongodb.DB; import net.vz.mongodb.jackson.JacksonDBCollection; public class MyBlogApplication extends Application<MyBlogConfiguration> { public static void main(String[] args) throws Exception { new MyBlogApplication().run(args); } @Override public String getName() { return "my-blog"; } @Override public void initialize(Bootstrap<MyBlogConfiguration> bootstrap) { // nothing to do yet } @Override public void run(MyBlogConfiguration configuration, Environment environment) throws Exception { Mongo mongo = new Mongo(configuration.getMongoHost(), configuration.getMongoPort()); MongoManaged mongoManaged = new MongoManaged(mongo); environment.lifecycle().manage(mongoManaged); final MongoHealthCheck mongoHealthCheck = new MongoHealthCheck(mongo); environment.healthChecks().register("mongo", mongoHealthCheck); DB db = mongo.getDB(configuration.getMongoDb()); JacksonDBCollection<Blog, String> blogs = JacksonDBCollection.wrap(db.getCollection("blogs"), Blog.class, String.class); final IndexResource indexResource = new IndexResource(blogs); environment.jersey().register(indexResource); final BlogResource blogResource = new BlogResource(blogs); environment.jersey().register(blogResource); } }
% git add src/main/java/com/example/myblog/MyBlogApplication.java % git add src/main/java/com/example/myblog/core/Blog.java % git add src/main/java/com/example/myblog/resources/BlogResource.java % git commit -m 'use mongoDB'
curl -i -X POST -H "Content-Type: application/json" -d '{"title":"getting started dropwizard 0.7.0 part2","url":"http://okamuuu.hatenablog.com/entry/2014/11/12/145356"}' http://localhost:8080/blogs
HTTP/1.1 204 No Content
Date: Sun, 16 Nov 2014 03:53:20 GMT
Content-Type: application/json
% curl http://localhost:8080
[{"id":"5467c915300414290c4253a6","title":"getting started dropwizard 0.7.0","url":"http://okamuuu.hatenablog.com/entry/2014/11/06/192836","publishedOn":1416087829129},{"id":"54681fb0300467ec3b406434","title":"getting started dropwizard 0.7.0 part2","url":"http://okamuuu.hatenablog.com/entry/2014/11/12/145356","publishedOn":1416110000144}]
% curl http://localhost:8080/blogs
[{"id":"5467c915300414290c4253a6","title":"getting started dropwizard 0.7.0","url":"http://okamuuu.hatenablog.com/entry/2014/11/06/192836","publishedOn":1416087829129},{"id":"54681fb0300467ec3b406434","title":"getting started dropwizard 0.7.0 part2","url":"http://okamuuu.hatenablog.com/entry/2014/11/12/145356","publishedOn":1416110000144}]