使用Dropwizard搭建一个Hello World

在开始之前我们需要准备一些环境,以下为本次所需相关工具:
系统:windows 7
JDK:1.8
开发工具:IntelliJ IDEA 2017.2.5
Maven:idea自带最新版本,采用本地化setting.xml(可以参考阿里巴巴的源配置,这样创建项目时自动下载要快很多倍)

本次编写demo参考依据为Dropwizard官网

下面我们开始进入正题,创建第一个基于Dropwizard的Hello World

一、创建一个maven的web项目

1.png
2.png
3.png
4.png
这里在创建时因为我本地已经存在了settings.xml,因此选择本地化配置文件,如果采用默认的则不需要进行选择。
5.png
6.png
点击图中标记的位置,将相关包进行下载并加入引用中,其实默认就一个junit包引用而已。

二、开始进行创建基础包路径

image.png
image.png
创建一个java目录,并设置该目录为根目录。

三、在pom.xml中引入dependency基础包。

<properties>
    <dependency.version>1.2.0</dependency.version>
  </properties>
  <dependencies>
    <!-- Dropwizard基础包 -->
    <dependency>
      <groupId>io.dropwizard</groupId>
      <artifactId>dropwizard-core</artifactId>
      <version>${dependency.version}</version>
    </dependency>

  </dependencies>

四、创建基础yml配置文件

image.png

该demo1.yml文件中的内容为:

#要打印的基础语句,其中%s是占位符。
template: Hello, %s!
#默认引用时的名字,这里名字叫做Stranger
defaultName: Stranger
在这里开始进入Dropwizard特性的一些编写了。
yml配置文件在官方解释中是这样说的:

Each Dropwizard application has its own subclass of the Configuration
class which specifies environment-specific parameters. These parameters are specified in a YAML configuration file which is deserialized to an instance of your application’s configuration class and validated.
The application we’ll be building is a high-performance Hello World service, and one of our requirements is that we need to be able to vary how it says hello from environment to environment. We’ll need to specify at least two things to begin with: a template for saying hello and a default name to use in case the user doesn’t specify their name.

因此我这里在写hello world时就直接按照上面说的来了。word在模板里面先用占位符,这样就可以[hello,小明]了o(╯□╰)o

五、创建基础Configuration,用于进行反序列化。

package com.demo1.helloworld.configuration;

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

/**
 * <b>TODO(com.demo1.helloworld.configuration @TODO)</b><br>
 * 版权所有 <a href="http://www.whndj.com">中国,華少</a><br>
 * 本软件仅对本次教程负责,其版权归属cnHuaShao,如需引用,请申明其版权所有人。
 *
 * @Description: 
 * @CreateDate 2017 2017/11/4 10:31 11 修改人:
 * <a href="mailto:lz2392504@gmail.com">cnHuaShao</a>
 * 修改备注:
 * @since V1.0
 */
public class HelloWorldConfiguration extends Configuration {

    /**
     * NotEmpty注解表示该变量不可以为空,之前我们在demo1.yml中已经编写了该变量对应的值,这个类主要是将其进行反序列化
     */
    @NotEmpty
    private String template;

    /**
     * NotEmpty注解表示该变量不可以为空,之前我们在demo1.yml中已经编写了该变量对应的值,这个类主要是将其进行反序列化
     * 默认值直接写入Stranger,这里根据自己的demo1.yml中defaultName默认值写的是什么就直接赋值什么,当然也可以不赋值,等具体引用时在赋值,不过建议还是写上去一个默认值,防止它出错。
     * 如果这两个值是空,则抛出系统异常
     */
    @NotEmpty
    private String defaultName = "Stranger";

    /**
     * 这里get set进行注解JsonProperty主要是为了对yml进行反序列化使用
     * @return
     */
    @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;
    }

}

官方给出的解释是:

Each Dropwizard application has its own subclass of the Configuration
class which specifies environment-specific parameters. These parameters are specified in a YAML configuration file which is deserialized to an instance of your application’s configuration class and validated.
The application we’ll be building is a high-performance Hello World service, and one of our requirements is that we need to be able to vary how it says hello from environment to environment. We’ll need to specify at least two things to begin with: a template for saying hello and a default name to use in case the user doesn’t specify their name.

六、进行创建基础Application

package com.demo1.helloworld.application;

import com.demo1.helloworld.configuration.HelloWorldConfiguration;
import io.dropwizard.Application;
import io.dropwizard.setup.Environment;

/**
 * <b>TODO(com.demo1.helloworld.application @TODO)</b><br>
 * 版权所有 <a href="http://www.whndj.com">中国,華少</a><br>
 * 本软件仅对本次教程负责,其版权归属cnHuaShao,如需引用,请申明其版权所有人。
 *
 * @Description: 
 * @CreateDate 2017 2017/11/4 10:58 11 修改人:
 * <a href="mailto:lz2392504@gmail.com">cnHuaShao</a>
 * 修改备注:
 * @since V1.0
 */
public class HelloWorldApplication  extends Application<HelloWorldConfiguration> {

    /**
     * 基础核心启动方法。dropwizard应用的核心方法。主要进行处理具体的业务逻辑的类
     * @param configuration
     * @param environment
     * @throws Exception
     */
    public void run(HelloWorldConfiguration configuration, Environment environment) throws Exception {

    }

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

七、创建一个基础表示类,其需要使其转成JSON时遵循RFC 1149

package com.demo1.helloworld.api;

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

/**
 * <b>TODO(com.demo1.helloworld.api @TODO)</b><br>
 * 版权所有 <a href="http://www.whndj.com">中国,華少</a><br>
 * 本软件仅对本次教程负责,其版权归属cnHuaShao,如需引用,请申明其版权所有人。
 *
 * @Description: 
 * @CreateDate 2017 2017/11/4 11:07 11 修改人:
 * <a href="mailto:lz2392504@gmail.com">cnHuaShao</a>
 * 修改备注:
 * @since V1.0
 */
public class Saying {

    private long id;

    /**
     * 内容最大长度不可以超过10
     */
    @Length(max = 10)
    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;
    }
}

八、创建Resource 类

package com.demo1.helloworld.resources;

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

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;

/**
 * <b>TODO(com.demo1.helloworld.resources @TODO)</b><br>
 * 版权所有 <a href="http://www.whndj.com">中国,華少</a><br>
 * 本软件仅对本次教程负责,其版权归属cnHuaShao,如需引用,请申明其版权所有人。
 *
 * @Description: 
 * @CreateDate 2017 2017/11/4 11:19 11 修改人:
 * <a href="mailto:lz2392504@gmail.com">cnHuaShao</a>
 * 修改备注:
 * @since V1.0
 */
@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();
    }

    /**
     * @Timed dropwizard会自动记录时间和它的调用率作为度量定时器
     * @param name
     * @return
     * @QueryParam 为URL链接后面的参数(url ?{参数名} = {参数值} 的格式)
     */
    @GET//客户端访问时只能通过get方法访问
    @Timed
    public Saying sayHello(@QueryParam("name") Optional<String> name) {
        //如果name参数没有传入,则调用defaultName的值,如果传入了,则采用name的值
        final String value = String.format(template, name.orElse(defaultName));
        //返回Saying对象
        return new Saying(counter.incrementAndGet(), value);
    }
}

九、修改第六步时创建的Application中的run方法。

public void run(HelloWorldConfiguration configuration, Environment environment) throws Exception {
        //声明一个resource,并传入初始化的值,该值由configuration读取的yml配置文件中的值。
        //可以启动多个resource
        final HelloWorldResource resource = new HelloWorldResource(
                configuration.getTemplate(),
                configuration.getDefaultName()
        );

        environment.jersey().register(resource);
    }

十、创建一个HealthCheck类

package com.demo1.helloworld.health;

import com.codahale.metrics.health.HealthCheck;

/**
 * <b>TODO(com.demo1.helloworld.health @TODO)</b><br>
 * 版权所有 <a href="http://www.whndj.com">中国,華少</a><br>
 * 本软件仅对本次教程负责,其版权归属cnHuaShao,如需引用,请申明其版权所有人。
 *
 * @Description: 
 * @CreateDate 2017 2017/11/4 11:37 11 修改人:
 * <a href="mailto:lz2392504@gmail.com">cnHuaShao</a>
 * 修改备注:
 * @since V1.0
 */
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, "模板测试");
        if (!saying.contains("模板测试")) {
            return Result.unhealthy("该模板不包含名称");
        }
        return Result.healthy();
    }


}

官方给出的解释是这样的:

Health checks give you a way of adding small tests to your application to allow you to verify that your application is functioning correctly in production. We strongly recommend that all of your applications have at least a minimal set of health checks.
其实这个是可有可无的,为了安全起见,这里先加上。(官方例子中要求加上o(╯□╰)o)

十一、再次修改第六步时创建的Application中的run方法。

public void run(HelloWorldConfiguration configuration, Environment environment) throws Exception {
        //声明一个resource,并传入初始化的值,该值由configuration读取的yml配置文件中的值。
        //可以启动多个resource
        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);
    }

十一、创建一个main方法。

package com.demo1.helloworld.main;

import com.demo1.helloworld.application.HelloWorldApplication;

/**
 * <b>TODO(com.demo1.helloworld.main @TODO)</b><br>
 * 版权所有 <a href="http://www.whndj.com">中国,華少</a><br>
 * 本软件仅对本次教程负责,其版权归属cnHuaShao,如需引用,请申明其版权所有人。
 *
 * @Description: 
 * @CreateDate 2017 2017/11/4 11:00 11 修改人:
 * <a href="mailto:lz2392504@gmail.com">cnHuaShao</a>
 * 修改备注:
 * @since V1.0
 */
public class HelloWorldMain {

    public static void main(String[] args) throws Exception {
        //启动helloworld
        new HelloWorldApplication().run(args);
    }
}

官方例子中main方法写在Application类中,我这里将其提出来了,方便大家理解。

至此,我们这个例子基本上写完了,开始进行打包。

十二、修改maven的pom.xml文件

<plugins>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <configuration>
                  <source>1.8</source>
                  <target>1.8</target>
              </configuration>
          </plugin>
          <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.demo1.helloworld.main.HelloWorldMain</mainClass>
                              </transformer>
                          </transformers>
                      </configuration>
                  </execution>
              </executions>
          </plugin>
          <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>
      </plugins>

十三、开始进行打包

image.png
image.png
image.png
image.png
image.png
image.png
image.png

十四、开始启动

image.png
image.png
image.png
image.png

看到上面的日志,则表明启动成功,打开浏览器访问:

http://localhost:8080/hello-world

image.png

http://localhost:8080/hello-world?name=xiaoming

image.png

至此,本次的Hello World编写完成。

所有代码均可以通过我的GItHub进行获取到,如有需要可以点击我的GitHub下载。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,052评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,267评论 3 397
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,518评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,457评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,474评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,143评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,728评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,650评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,184评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,269评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,415评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,083评论 5 348
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,775评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,257评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,389评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,777评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,419评论 2 359

推荐阅读更多精彩内容