dropwizard框架学习

Dropwizard:


Overview:

Dropwizard straddles the line between being a library and a framework. 

跨越了库和框架之间的界限。


Jetty for Http:

由于不能成为一个没有HTTP的web应用程序,Dropwizard使用Jetty HTTP库将一个HTTP服务器嵌入到项目中。与把应用程序交给复杂的应用程序服务器不同,Dropwizard有个main方法来启动我们的服务器。运行应用程序是一个简单的过程消除了很多Java令人讨厌的生产方面的过程(没有PermGen问题,应用服务器配置和维护,没有晦涩难懂的部署工具,没有类装入器问题,没有隐藏应用程序日志,没有试图优化一个垃圾收集器与多个应用程序工作负载),允许使用现有的Unix进程管理工具。


Jersery for REST:

为了构建基于rest的web应用程序,我们在特性或性能方面没有发现任何优于Jersey(jax - rs参考实现)的东西。它允许您编写干净的、可测试的类,将HTTP请求优雅地映射到简单的Java对象。它支持流输出、矩阵URI参数、条件GET请求,以及更多

 jersey是基于Java的一个轻量级RESTful风格的WebServices框架.


Jackson for JSON:

就数据格式而言,JSON已经成为web的通用语言,而Jackson是JVM中的JSON之王。除了闪电般的快速,它还有一个复杂的对象映射器,允许直接导出领域模型。


Metrics for metrics:

度量库将事情进行了分析,为在生产环境中的代码行为提供了无与伦比的洞察。


简而言之:

Dropwizard是一个开源的Java框架,用于开发OPS友好、高性能的基于REST的后端,提供同类最佳的Java库到一个嵌入式应用程序包。有几下几个部分:

1、嵌入式Jetty:每一个应用程序被打包成一个jar(而不是war)文件,并开始自己的嵌入式Jetty容器。没有任何war文件和外部servlet容器。(每个Dropwizard应用程序有一个启动Jetty容器的主程序。这意味着,完全可以把应用程序作为一个主程序在IDE中运行和调试。所以就没有重新编译或部署war文件

2、JAX-RS:Jersey是用来写基于REST的Web服务的。

3、JSON:REST服务用的是JSON,Jackson库用来做所有的JSON处理。

4、Hibernate验证:Dropwizard使用Hibernate验证API进行声明性验证。

5、指标:Dropwizard支持监控使用标准库,它在监控代码方面有无与伦比的洞察力。

6、日志:使用Logback和SLF4J完成。


开发:

1、pom.xml文件:


    0.9.2



    io.dropwizard
    dropwizard-core
    ${dropwizard.version}

2、Configuration类

每个Dropwizard应用都有一个Configuration的子类,指定环境相关的参数。这些参数在一个YAML配置文件中指定。该配置会被反序列化,得到应用配置对应的Configuration实例并进行验证。这个配置文件中指定的参数,会被映射到我们项目的一个类。

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

public class HelloWorldConfiguration extends Configuration {
    @NotEmpty
    private String template;

    @NotEmpty
    private String defaultName = "Stranger";

    @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;
    }
}

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

defaultName和template的get 和set 方法都被@JsonProperty标注,这不止允许jackson从YAML配置文件反序列化,同样允许它序列化。

YAML:与配置类中的变量一一对应

template: Hello, %s!
defaultName: Stranger
3、Application类
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 void main(String[] args) throws Exception {
        new HelloWorldApplication().run(args);
    }

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

    @Override
    public void initialize(Bootstrap bootstrap) {
        // nothing to do yet
    }

    @Override
    public void run(HelloWorldConfiguration configuration,
                    Environment environment) {
        // nothing to do yet
    }

}
HelloWorldApplication使用应用程序的configuration进行参数化。

initialize方法用于配置应用在正式启动之前所需:包,配置源等。同时我们需要加入一个main方法,这是我们应用的入口。

4、Representation类(POJO类)

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

public class Saying {
    private long id;

    @Length(max = 3)
    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;
    }
}
这是一个非常简单的POJO,有几点需要注意。首先,它不可更改,这使得它在多线程和单线程环境中很容易推断出实例。其次,它使用javabean来表示id和content属性,这允许jackson把它序列化为我们所需的json。 jackson对象的映射代码将会使用getId()返回的对象来填充JSON对象的id字段,content同理。 bean利用验证来确保content不大于3。

5、Resource Class(可以调用的接口api)

Jersey资源是DW应用程序的肉和土豆。每个资源类都与URL相关联。对于应用程序来说,需要一个resources来通过url:/helloworld来返回新的Saying实例对象。

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 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();
    }

    @GET
    @Timed
    public Saying sayHello(@QueryParam("name") Optional name) {
        final String value = String.format(template, name.or(defaultName));
        return new Saying(counter.incrementAndGet(), value);
    }
}
HelloWorldResource有两个注释:@Path和@Produces。@Path("/hello-world")告诉Jersey这个resource可以通过 "/hello-world"URL被访问。 @Produces(MediaType.APPLICATION_JSON)让Jersey的内容协商代码知道这个资源产生的是application/json。
@QueryParam("name")告诉Jersey把在查询参数中的name映射到方法中的name中。如果一个客户发送请求到:/hello-world?name=Dougie,sayHello 方法将会伴随Optional.of("Dougie")被调用。如果查询参数中没有name,sayHello将会伴随着Optional.absent()被调用。

在sayHello方法里面,我们增加计数器的值,使用String.format来格式化模板,返回一个新的Saying实例。因为sayHello被@Timed注释,DW将会自动调用他的持续时间和速率记录为度量定时器。

6、Registering A Resource

在HelloworldApplication中写run方法:

@Override
public void run(HelloWorldConfiguration configuration,
                Environment environment) {
    final HelloWorldResource resource = new HelloWorldResource(
        configuration.getTemplate(),
        configuration.getDefaultName()
    );
    environment.jersey().register(resource);
}
当我们的应用程序启动时,我们将从配置文件中创建一个新的资源类实例,并将其交给环境,它就像一个注册表,您的应用程序可以做的所有事情。

7、Health Check
Health Check提供了一种方法,可以在应用程序中添加小测试,以验证应用程序在生产中是否正常运行。强烈建议您的所有应用程序至少有最少的Health Check集。

由于在应用程序运行时,格式化字符串不太可能失败(不像数据库连接池),因此需要在这里获得一点创造性。

模板:

import com.codahale.metrics.health.HealthCheck;

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, "TEST");
        if (!saying.contains("TEST")) {
            return Result.unhealthy("template doesn't include a name");
        }
        return Result.healthy();
    }
}
TemplateHealthCheck检查两件事:所提供的模板实际上是格式良好的格式字符串,而模板实际上是使用给定的名称产生输出。
添加Health Check:

@Override
public void run(HelloWorldConfiguration configuration,
                Environment environment) {
    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);
}
8、Building Fat JARs

在pom.xml中加入:


        
            
                org.apache.maven.plugins
                maven-shade-plugin
                2.3
                
                    true
                    
                        
                            *:*
                            
                                META-INF/*.SF
                                META-INF/*.DSA
                                META-INF/*.RSA
                            
                        
                    
                
                
                    
                        package
                        
                            shade
                        
                        
                            
                                
                                
                                    app.WeChatApplication
                                
                            
                        
                    
                
            
            
                org.apache.maven.plugins
                maven-jar-plugin
                2.4
                
                    
                        
                            true
                        
                    
                
            
        
    
在项目目录运行  mvn package,接着运行java -jar target/hello-world-0.0.1-SNAPSHOT.jar  server hello - world .yml

你可能感兴趣的:(框架架构学习)