java dropwizard_Dropwizard简单入门
其它开发库
除了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简单入门相关推荐
- Java正则表达式简单入门
正则表达式,又称规则表达式.(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表达式是对字符串(包括普通字符(例如,a 到 z ...
- java jsf_JSF简单入门
3.JSF的生命周期 FacesServlet 充当用户和 JSF 应用程序之间的纽带.它在明确限定的 JSF 生命周期(规定了用户请求之间的整个事件流)的范围内工作. a.当JSF页面上的一个事件发 ...
- JAVA Bean和XML之间的相互转换 - XStream简单入门
JAVA Bean和XML之间的相互转换 - XStream简单入门 背景介绍 XStream的简介 注解简介 应用实例 背景介绍 我们在工作中经常 遇到文件解析为数据或者数据转化为xml文件的情况, ...
- 《Java Web开发入门很简单》学习笔记
<Java Web开发入门很简单>学习笔记 1123 第1章 了解Java Web开发领域 Java Web主要涉及技术包括:HTML.JavaScript.CSS.JSP.Servlet ...
- java中logger_Java日志系统---Logger之简单入门
Java 中自带的日志系统,今天抽空了解了一点,算是入了门,所以将自己的一些心得记录下来,以备日后查看,有兴趣的朋友,看到此文章,觉得有错误或需要添加的地方,请在下方评论留言,大家可以共同进步,谢谢: ...
- 【java开发系列】—— spring简单入门示例
回顾 1 JDK安装 2 Struts2简单入门示例 前言 作为入门级的记录帖,没有过多的技术含量,简单的搭建配置框架而已.这次讲到spring,这个应该是SSH中的重量级框架,它主要包含两个内容:控 ...
- 【JAVA零基础入门系列】Day2 Java集成开发环境IDEA
[JAVA零基础入门系列](已完结)导航目录 Day1 开发环境搭建 Day2 Java集成开发环境IDEA Day3 Java基本数据类型 Day4 变量与常量 Day5 Java中的运算符 Day ...
- java程序员入门先学什么开发者工具
学习java编程语言,那么开发工具是肯定少不了的,程序员入门基础中开发工具是一定要学会的,可以帮助开发者们提高开发效率.更优雅的写代码.由于开发者涉及的技术领域众多,以后端开发者的视角盘点平时可能用得 ...
- Java学习从入门到精通的学习建议
想要学好java技术,首先打好基础很重要,不论学什么基础都是重中之重,学习Java更是如此.如:基础语法.核心类库.面向对象编程.异常.集合.IO流等基础如果学不好,那么后边更深入的语法也不容易学会. ...
最新文章
- scala语法注意点小结
- Spring MVC入门示例教程--表单处理
- 【转】走进windows编程的世界-----对话框、文本框、按钮
- 教程-Delphi第三方控件安装卸载指南
- MYSQL问题解决方案:Access denied for user ‘root‘@‘localhost‘ (using password:YES)
- iis7网站可用php吗,在IIS7下面添加对PHP网页的支持
- Chaff Bugs: Deterring Attackers by Making Software Buggier
- 数据结构与算法 哈希表的特点
- Vue.js 第5章 webpack配置
- #9733;宣传广告变成社会标准
- malloc(): smallbin double linked list corrupted:
- 廉颇老矣?尚能饭否?64岁的Python之父被微软录取!
- python网络编程原理_图解Python网络编程
- 1293A-ConneR and the A.R.C. Markland-N(ArrayList、二分查找)
- 十分钟入门Visio,不行来砍我!
- iOS知识点汇总复习
- 【STC8A8K64D4开发板】——开发板程序下载
- 二本逆袭进百度,我总结了这些经验
- 优秀广告设计作品常用的几大设计思维
- md5在线加密解密是不是什么都能解密?为什么我的没有解出来呢?
热门文章
- Excel函数DAY和EOMONTH
- Linux下IIC驱动编写,介绍IIC子系统框架的使用
- JDK命令三、jstat命令(Java Virtual Machine Statistics Monitoring Tool)
- python 调用widows 微信快捷键,进行自动发送微信消息
- linux系统下默认目录,linux系统默认的目录意思
- NC20684 wpy的请求(SPFA)
- 优化方法(Tuning methodology)
- CTF gif分离与像素点提取(running_pixel)
- Oracle网络原理及配置
- 【100%通过率】华为OD机试真题 Python 实现【计算数组中心位置】【2022.11 Q4 新题】