其它开发库

除了Jetty、Jersey 和 Jackson,Dropwizard还包含了很多其它非常有帮助的开发库:

Guava:支持不可变数据结构,提供日益丰富的Java工具类加速开发。

Logback 和 slf4j 可以提供高效灵活的日志功能。

Hibernate Validator(JSR-349_ 参考实现)提供了简洁、声明式的用户输入验证框架,生成非常有用支持i18n的错误信息。

Apache HttpClient 和 Jersey 客户端开发库提供了与其它Web服务的底层和高层交互。

JDBI:为Java关系数据库提供了最直接的方式交互。

Liquibase:在开发和发布周期中,为数据库schema提供全程检查。支持高层数据库重构,取代了一次性DDL脚本。

Freemarker 和 Mustache为面向用的应用程序提供了简单的模板系统。

Joda Time:完整强大的时间日期处理开发库。

简单示例

推荐使用Maven构建新的Dropwizard应用,首先,在POM中加入 dropwizard.version 属性及最新版本:

INSERT VERSION HERE

把 dropwizard-core 加为依赖项:

io.dropwizard

dropwizard-core

${dropwizard.version}

1. 新建Configuration类

每个DW应用都有他自己的子类:Configuration,这个类指定环境中特定的参数。这些参数在YAML类型的配置文件中被指定,其被反序列化为应用程序配置类的实例并验证。(这句话的意思就是这个配置文件中指定的参数,会被映射到我们项目的一个类)我们将要构建的是一个helloworld高性能服务。我们的一个要求就是我们需要能够在不同的环境中让它说hello,在开始之前我们需要指定至少两个内容:一个说hello的模板 还有一个默认的名字以防用户忘记指定。

package com.example.helloworld;

import com.example.helloworld.core.Template;

import com.fasterxml.jackson.annotation.JsonProperty;

import com.google.common.collect.ImmutableMap;

import io.dropwizard.Configuration;

import io.dropwizard.db.DataSourceFactory;

import org.hibernate.validator.constraints.NotEmpty;

import javax.validation.Valid;

import javax.validation.constraints.NotNull;

import java.util.Collections;

import java.util.Map;

public class HelloWorldConfiguration extends Configuration {

@NotEmpty

private String template;

@NotEmpty

private String defaultName = "Stranger";

@Valid

@NotNull

private DataSourceFactory database = new DataSourceFactory();

@NotNull

private Map> viewRendererConfiguration = Collections.emptyMap();

@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 defaultName) {

this.defaultName = defaultName;

}

public Template buildTemplate() {

return new Template(template, defaultName);

}

@JsonProperty("database")

public DataSourceFactory getDataSourceFactory() {

return database;

}

@JsonProperty("database")

public void setDataSourceFactory(DataSourceFactory dataSourceFactory) {

this.database = dataSourceFactory;

}

@JsonProperty("viewRendererConfiguration")

public Map> getViewRendererConfiguration() {

return viewRendererConfiguration;

}

@JsonProperty("viewRendererConfiguration")

public void setViewRendererConfiguration(Map> viewRendererConfiguration) {

final ImmutableMap.Builder> builder = ImmutableMap.builder();

for (Map.Entry> entry : viewRendererConfiguration.entrySet()) {

builder.put(entry.getKey(), ImmutableMap.copyOf(entry.getValue()));

}

this.viewRendererConfiguration = builder.build();

}

}

当这个类被从YAML配置文件反序列化的时候,他会从YAML对象中获取两个根层次的变量:template 用来说helloworld的模板。defaultName 默认的名字。template和defaultName都用@NotEmpty被注释,所以在YAML配置文件中如果有空值或者忘了其中一者,异常将会被抛出,我们的应用将不会被启动。defaultName和template的get 和set 方法都被@JsonProperty标注,这不止允许jackson从YAML配置文件反序列化,同样允许它序列化。

然后我们创建一个YAML的配置文件,内容如下:

template: Hello, %s!defaultName: Stranger

2. 新建Application类

结合我们项目中的Configuration子类,我们的Application的子类形成了我们DW的应用的核心,Application的子类把不同的提供各式各样功能的包和命令拉取到了一起。

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{public static voidmain(String[] args) throws Exception {newHelloWorldApplication().run(args);

}

@OverridepublicString getName() {return "hello-world";

}

@Overridepublic void initialize(Bootstrapbootstrap) {//nothing to do yet

}

@Overridepublic voidrun(HelloWorldConfiguration configuration,

Environment environment) {//nothing to do yet

}

}

正如我们所看到的,HelloWorldApplication使用应用程序的configuration进行参数化,(因为用了我们的HelloWorldConfiuration,而它是Configuration的子类),initialize方法用于配置应用在正式启动之前所需:包,配置源等,同时我们需要加入一个main方法,这是我们应用的入口,到目前为止,我们并没有实现任何的功能,所以我们的run方法有点无趣,让我们开始丰富它。

3. 新建Representation类

在我们开始继续我们的程序之前,我们需要停下来思考一下我们程序的API。幸运的是,我们的应用需要符合行业标准RFC 1149,它指定了helloworld saying的如下json表达形式:

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

id字段是唯一标识,content是文字内容。下面是representation实现,一个简单的POJO类:

package com.example.helloworld.api;

import com.fasterxml.jackson.annotation.JsonProperty;

import org.hibernate.validator.constraints.Length;public classSaying {private longid;

@Length(max= 3)privateString content;publicSaying() {//Jackson deserialization

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

}

@JsonPropertypublic longgetId() {returnid;

}

@JsonPropertypublicString getContent() {returncontent;

}

}

这是一个非常简单的POJO,但是有些需要注意的地方。首先,他是不可更改的。这使得saying在多线程环境和单线程环境非常容易被推理。其次,它使用java的JavaBean来保存id和content属性。这允许jackson把他序列化为我们需要的JSON。jackson对象的映射代码将会使用getId()返回的对象来填充JSON对象的id字段,content同理。最后,bean利用验证来确保内容不大于3。

4. 新建Resource类

Jersey资源是DW应用程序的主要内容,每个资源类都与URL相关联(这个很重要,后面有说),对于我们的应用程序来说,我们需要一个resources来通过url:/helloworld来返回新的Saying实例对象。

package com.example.helloworld.resources;

import com.example.helloworld.api.Saying;

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;

@Path("/hello-world")

@Produces(MediaType.APPLICATION_JSON)public classHelloWorldResource {privatefinal String template;privatefinal String defaultName;privatefinal AtomicLong counter;publicHelloWorldResource(String template, String defaultName) {this.template =template;this.defaultName =defaultName;this.counter = newAtomicLong();

}

@GET

@Timedpublic Saying sayHello(@QueryParam("name") Optionalname) {

final String value=String.format(template, name.or(defaultName));return newSaying(counter.incrementAndGet(), value);

}

}

HelloWorldResource有两个声明:@Path和@Produces。@Path("/hello-world")告诉Jersey这个resource可以通过 "/hello-world"URL被访问。

@Produces(MediaType.APPLICATION_JSON)让Jersey的内容协商代码知道这个资源产生的是application/json.

HelloWorldResource构造器接收两个参数,创建saying的template和当用户没有指明名字时的默认名称,AtomicLong为我们提供一种线程安全,简易的方式去生成(ish)ID。sayHello方法是这个类的肉,也是一个非常简单的方法。@QueryParam("name")告诉Jersey把在查询参数中的name映射到方法中的name中。如果一个客户发送请求到:/hello-world?name=Dougie,sayHello 方法将会伴随Optional.of("Dougie")被调用。如果查询参数中没有name,sayHello将会伴随着Optional.absent()被调用。在sayHello方法里面,我们增加计数器的值,使用String.format来格式化模板,返回一个新的Saying实例。因为sayHello被@Timed注释,DW将会自动调用他的持续时间和速率记录为度量定时器。一旦sayHello返回,Jersey将会采用Saying的实例,并寻找一个提供程序类来将Saying实例写为:application/json。

5. 注册Resource

在这些正式工作之前,我们需要到HelloWorldApplication中,并将新的resouce加入其中,在run方法中我们可以读取到HelloWorldConfiguration的template和defaultName实例,创建一个新的HelloWorldResource实例,并将其加入到新的Jersey环境中。我们HelloWorldApplication中新的run方法如下:

@Overridepublic voidrun(HelloWorldConfiguration configuration,

Environment environment) {

final HelloWorldResource resource= newHelloWorldResource(

configuration.getTemplate(),

configuration.getDefaultName()

);

environment.jersey().register(resource);

}

当我们的应用启动的时候,我们使用配置文件中的参数创建一个新的资源类实例,并传递给environment.

转自:http://blog.csdn.net/qq_23660243/article/details/54406075 以及 http://hao.jobbole.com/dropwizard/

java dropwizard_Dropwizard简单入门相关推荐

  1. Java正则表达式简单入门

    正则表达式,又称规则表达式.(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表达式是对字符串(包括普通字符(例如,a 到 z ...

  2. java jsf_JSF简单入门

    3.JSF的生命周期 FacesServlet 充当用户和 JSF 应用程序之间的纽带.它在明确限定的 JSF 生命周期(规定了用户请求之间的整个事件流)的范围内工作. a.当JSF页面上的一个事件发 ...

  3. JAVA Bean和XML之间的相互转换 - XStream简单入门

    JAVA Bean和XML之间的相互转换 - XStream简单入门 背景介绍 XStream的简介 注解简介 应用实例 背景介绍 我们在工作中经常 遇到文件解析为数据或者数据转化为xml文件的情况, ...

  4. 《Java Web开发入门很简单》学习笔记

    <Java Web开发入门很简单>学习笔记 1123 第1章 了解Java Web开发领域 Java Web主要涉及技术包括:HTML.JavaScript.CSS.JSP.Servlet ...

  5. java中logger_Java日志系统---Logger之简单入门

    Java 中自带的日志系统,今天抽空了解了一点,算是入了门,所以将自己的一些心得记录下来,以备日后查看,有兴趣的朋友,看到此文章,觉得有错误或需要添加的地方,请在下方评论留言,大家可以共同进步,谢谢: ...

  6. 【java开发系列】—— spring简单入门示例

    回顾 1 JDK安装 2 Struts2简单入门示例 前言 作为入门级的记录帖,没有过多的技术含量,简单的搭建配置框架而已.这次讲到spring,这个应该是SSH中的重量级框架,它主要包含两个内容:控 ...

  7. 【JAVA零基础入门系列】Day2 Java集成开发环境IDEA

    [JAVA零基础入门系列](已完结)导航目录 Day1 开发环境搭建 Day2 Java集成开发环境IDEA Day3 Java基本数据类型 Day4 变量与常量 Day5 Java中的运算符 Day ...

  8. java程序员入门先学什么开发者工具

    学习java编程语言,那么开发工具是肯定少不了的,程序员入门基础中开发工具是一定要学会的,可以帮助开发者们提高开发效率.更优雅的写代码.由于开发者涉及的技术领域众多,以后端开发者的视角盘点平时可能用得 ...

  9. Java学习从入门到精通的学习建议

    想要学好java技术,首先打好基础很重要,不论学什么基础都是重中之重,学习Java更是如此.如:基础语法.核心类库.面向对象编程.异常.集合.IO流等基础如果学不好,那么后边更深入的语法也不容易学会. ...

最新文章

  1. scala语法注意点小结
  2. Spring MVC入门示例教程--表单处理
  3. 【转】走进windows编程的世界-----对话框、文本框、按钮
  4. 教程-Delphi第三方控件安装卸载指南
  5. MYSQL问题解决方案:Access denied for user ‘root‘@‘localhost‘ (using password:YES)
  6. iis7网站可用php吗,在IIS7下面添加对PHP网页的支持
  7. Chaff Bugs: Deterring Attackers by Making Software Buggier
  8. 数据结构与算法 哈希表的特点
  9. Vue.js 第5章 webpack配置
  10. #9733;宣传广告变成社会标准
  11. malloc(): smallbin double linked list corrupted:
  12. 廉颇老矣?尚能饭否?64岁的Python之父被微软录取!
  13. python网络编程原理_图解Python网络编程
  14. 1293A-ConneR and the A.R.C. Markland-N(ArrayList、二分查找)
  15. 十分钟入门Visio,不行来砍我!
  16. iOS知识点汇总复习
  17. 【STC8A8K64D4开发板】——开发板程序下载
  18. 二本逆袭进百度,我总结了这些经验
  19. 优秀广告设计作品常用的几大设计思维
  20. md5在线加密解密是不是什么都能解密?为什么我的没有解出来呢?

热门文章

  1. Excel函数DAY和EOMONTH
  2. Linux下IIC驱动编写,介绍IIC子系统框架的使用
  3. JDK命令三、jstat命令(Java Virtual Machine Statistics Monitoring Tool)
  4. python 调用widows 微信快捷键,进行自动发送微信消息
  5. linux系统下默认目录,linux系统默认的目录意思
  6. NC20684 wpy的请求(SPFA)
  7. 优化方法(Tuning methodology)
  8. CTF gif分离与像素点提取(running_pixel)
  9. Oracle网络原理及配置
  10. 【100%通过率】华为OD机试真题 Python 实现【计算数组中心位置】【2022.11 Q4 新题】