{"id":429742,"date":"2024-08-21T21:09:08","date_gmt":"2024-08-21T21:09:08","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=429742"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=429742","title":{"rendered":"<span>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043d\u0430 Java \u0441 Dropwizard<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><em>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440!<\/em><\/p>\n<p><strong>Dropwizard<\/strong>\u00a0\u2014 \u044d\u0442\u043e \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u00a0\u0446\u0435\u043b\u044c\u044e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 RESTful \u0432\u0435\u0431\u2011\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u044f \u0432\u00a0\u0441\u0435\u0431\u0435 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u0445 \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u0412\u00a0\u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u0435 \u043b\u0435\u0436\u0430\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b:<\/p>\n<ul>\n<li>\n<p><strong>Jetty<\/strong>\u00a0\u2014 \u043b\u0435\u0433\u043a\u043e\u0432\u0435\u0441\u043d\u044b\u0439 HTTP \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u043e\u0432, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u0432\u044b\u0441\u043e\u043a\u0443\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u00a0\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p><strong>Jersey<\/strong>\u00a0\u2014 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f RESTful \u0432\u0435\u0431\u2011\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0438 \u043c\u043e\u0449\u043d\u044b\u0439 API \u0434\u043b\u044f\u00a0\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 REST API.<\/p>\n<\/li>\n<li>\n<p><strong>Jackson<\/strong>\u00a0\u2014 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f\u00a0\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 Java \u0432\u00a0JSON \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e, \u0448\u0438\u0440\u043e\u043a\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u0441\u0432\u043e\u0435\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e \u0438 \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c\u044e.<\/p>\n<\/li>\n<li>\n<p><strong>Metrics<\/strong>\u00a0\u2014 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f\u00a0\u0441\u0431\u043e\u0440\u0430 \u0438 \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u043c\u0435\u0442\u0440\u0438\u043a \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0430\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u00a0\u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, Dropwizard \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432\u00a0\u0441\u0435\u0431\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438, \u043b\u043e\u0433\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<h4>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c<\/h4>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441\u00a0\u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430. \u041f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e, \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f JDK,\u00a0\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0435\u0440\u0441\u0438\u0438 11\u00a0\u0438\u043b\u0438\u00a0\u0432\u044b\u0448\u0435. \u0414\u0430\u043b\u0435\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0441\u0431\u043e\u0440\u043a\u0438: <strong>Maven<\/strong> \u0438 <strong>Gradle<\/strong>. \u041e\u0431\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f Dropwizard, \u0438 \u0432\u044b\u0431\u043e\u0440 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u0441\u043a\u043e\u0440\u0435\u0435 \u043e\u0442\u00a0\u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0414\u043b\u044f\u00a0\u0442\u0435\u0445, \u043a\u0442\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u0435\u0442 Maven, \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430. \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 Maven\u2011\u043f\u0440\u043e\u0435\u043a\u0442, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0432 <code>pom.xml<\/code> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438. \u041f\u0440\u0438\u043c\u0435\u0440 \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438:<\/p>\n<pre><code class=\"xml\">&lt;dependency&gt;     &lt;groupId&gt;io.dropwizard&lt;\/groupId&gt;     &lt;artifactId&gt;dropwizard-core&lt;\/artifactId&gt;     &lt;version&gt;2.1.0&lt;\/version&gt; &lt;\/dependency&gt;<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>mvn clean install.<\/code><\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b\u0431\u043e\u0440 \u043f\u0430\u043b Gradle, \u0442\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430 <code>build.gradle<\/code> \u0441\u00a0\u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439:<\/p>\n<pre><code>plugins {     id 'java' }  repositories {     mavenCentral() }  dependencies {     implementation 'io.dropwizard:dropwizard-core:2.1.0' }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>.\/gradlew build<\/code>, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.<\/p>\n<p>\u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u0435\u043d \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c <code>io.dropwizard.Application<\/code> \u0438 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>run<\/code>. \u0412\u043e\u0442 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"java\">public class HelloWorldApplication extends Application&lt;HelloWorldConfiguration&gt; {     public static void main(String[] args) throws Exception {         new HelloWorldApplication().run(args);     }      @Override     public void run(HelloWorldConfiguration configuration, Environment environment) {         final HelloWorldResource resource = new HelloWorldResource(             configuration.getTemplate(),             configuration.getDefaultName()         );         environment.jersey().register(resource);     } }<\/code><\/pre>\n<p>\u041e\u0431\u044b\u0447\u043d\u043e, \u043f\u0440\u043e\u0435\u043a\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d \u043d\u0430\u00a0\u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0447\u0430\u0441\u0442\u0435\u0439:<\/p>\n<ul>\n<li>\n<p><strong>src\/main\/java<\/strong>\u00a0\u2014 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434.<\/p>\n<\/li>\n<li>\n<p><strong>src\/main\/resources<\/strong>\u00a0\u2014 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b, \u0432\u043a\u043b\u044e\u0447\u0430\u044f <code>config.yml<\/code>.<\/p>\n<\/li>\n<li>\n<p><strong>target<\/strong>\u00a0\u2014 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f, \u043a\u0443\u0434\u0430 \u043f\u043e\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b.<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b <code>config.yml<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c \u0432\u00a0\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041f\u0440\u0438\u043c\u0435\u0440 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430:<\/p>\n<pre><code class=\"yaml\">server:   applicationConnectors:     - type: http       port: 8080   adminConnectors:     - type: http       port: 8081  logging:   level: INFO   loggers:     com.example.helloworld: DEBUG<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f, \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0431\u0435\u0437\u00a0\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043a\u043e\u0434.<\/p>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441<\/h2>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e\u00a0\u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c,\u00a0\u2014 \u044d\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c REST API. Dropwizard \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u043c \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0441\u00a0Jersey. \u041d\u0430\u0447\u043d\u0435\u043c \u0441\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 URL\u2011\u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442:<\/p>\n<pre><code class=\"java\">import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType;  @Path(\"\/hello-world\") @Produces(MediaType.APPLICATION_JSON) public class HelloWorldResource {     @GET     public String sayHello() {         return \"{\\\"message\\\":\\\"Hello, World!\\\"}\";     } }<\/code><\/pre>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043a\u043b\u0430\u0441\u0441 <code>HelloWorldResource<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c GET\u2011\u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u043e\u00a0\u043f\u0443\u0442\u0438 <code>\/hello-world<\/code> \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 JSON\u2011\u043e\u0442\u0432\u0435\u0442. \u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 <code>@Path<\/code> \u0438 <code>@GET<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0438 HTTP\u2011\u043c\u0435\u0442\u043e\u0434 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e\u0442 \u0440\u0435\u0441\u0443\u0440\u0441 \u043d\u0430\u0447\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u00a0\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438:<\/p>\n<pre><code class=\"java\">import io.dropwizard.Application; import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment;  public class HelloWorldApplication extends Application&lt;HelloWorldConfiguration&gt; {     public static void main(String[] args) throws Exception {         new HelloWorldApplication().run(args);     }      @Override     public void run(HelloWorldConfiguration configuration, Environment environment) {         final HelloWorldResource resource = new HelloWorldResource();         environment.jersey().register(resource);     } }<\/code><\/pre>\n<p>\u041a\u043b\u0430\u0441\u0441 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u0447\u043a\u043e\u0439 \u0432\u0445\u043e\u0434\u0430 \u0432\u00a0\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0440\u0435\u0441\u0443\u0440\u0441 \u0432\u00a0\u043c\u0435\u0442\u043e\u0434\u0435 <code>run<\/code>, \u0447\u0442\u043e\u0431\u044b Dropwizard \u0437\u043d\u0430\u043b, \u043a\u0430\u043a\u00a0\u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 HTTP\u2011\u0437\u0430\u043f\u0440\u043e\u0441\u044b.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a\u00a0\u0434\u0440\u0443\u0433\u043e\u0439 \u0447\u0430\u0441\u0442\u0438\u00a0\u2014 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 CRUD \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e\u00a0\u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u00a0\u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c\u044e <code>Person<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u043c\u0435\u0435\u0442 ID, \u0438\u043c\u044f \u0438 \u0432\u043e\u0437\u0440\u0430\u0441\u0442:<\/p>\n<pre><code class=\"java\">import com.fasterxml.jackson.annotation.JsonProperty;  public class Person {     private long id;     private String name;     private int age;      public Person() {}      public Person(long id, String name, int age) {         this.id = id;         this.name = name;         this.age = age;     }      @JsonProperty     public long getId() {         return id;     }      @JsonProperty     public String getName() {         return name;     }      @JsonProperty     public int getAge() {         return age;     } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0440\u0435\u0441\u0443\u0440\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u0434\u043b\u044f <code>Person<\/code>:<\/p>\n<pre><code class=\"java\">import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.*;  @Path(\"\/people\") @Produces(MediaType.APPLICATION_JSON) public class PersonResource {     private final Map&lt;Long, Person&gt; personDB = new HashMap&lt;&gt;();      @POST     public Response createPerson(Person person) {         personDB.put(person.getId(), person);         return Response.status(Response.Status.CREATED).entity(person).build();     }      @GET     @Path(\"\/{id}\")     public Person getPerson(@PathParam(\"id\") long id) {         Person person = personDB.get(id);         if (person == null) {             throw new WebApplicationException(\"Person not found\", Response.Status.NOT_FOUND);         }         return person;     }      @PUT     @Path(\"\/{id}\")     public Person updatePerson(@PathParam(\"id\") long id, Person person) {         if (!personDB.containsKey(id)) {             throw new WebApplicationException(\"Person not found\", Response.Status.NOT_FOUND);         }         personDB.put(id, person);         return person;     }      @DELETE     @Path(\"\/{id}\")     public Response deletePerson(@PathParam(\"id\") long id) {         Person person = personDB.remove(id);         if (person == null) {             throw new WebApplicationException(\"Person not found\", Response.Status.NOT_FOUND);         }         return Response.status(Response.Status.NO_CONTENT).build();     } }<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u0440\u0435\u0441\u0443\u0440\u0441 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 CRUD \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u0417\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>HashMap<\/code> \u043a\u0430\u043a\u00a0\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u043e\u00a0\u0432\u00a0\u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u041d\u0435\u00a0\u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043e\u00a0\u0442\u043e\u043c, \u0447\u0442\u043e\u00a0\u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c HTTP\u2011\u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442\u044b. \u0412\u00a0\u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u043c \u0432\u044b\u0448\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442 <code>Response<\/code> \u0434\u043b\u044f\u00a0\u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0443\u0441\u0430\u043c\u0438 HTTP \u0438 \u0442\u0435\u043b\u043e\u043c \u043e\u0442\u0432\u0435\u0442\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <code>Person<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u0442\u0443\u0441 <code>201 Created<\/code>, \u0447\u0442\u043e\u00a0\u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u00a0\u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>@PathParam<\/code> \u0434\u043b\u044f\u00a0\u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0438\u0437\u00a0URL, \u0430 <code>@JsonProperty<\/code> \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432\u00a0JSON \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0432\u00a0\u0432\u0438\u0437\u0430\u0440\u0434\u0435 \u0435\u0441\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f\u00a0\u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 <code>@NotNull<\/code>, <code>@Size<\/code>, <code>@Min<\/code>, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e\u00a0\u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c \u043f\u0435\u0440\u0435\u0434 \u0438\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438:<\/p>\n<pre><code class=\"java\">import javax.validation.constraints.Min; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull;  public class Person {     private long id;      @NotEmpty     private String name;      @Min(0)     private int age;      \/\/ \u0413\u0435\u0442\u0442\u0435\u0440\u044b \u0438 \u0441\u0435\u0442\u0442\u0435\u0440\u044b }<\/code><\/pre>\n<p>\u041b\u043e\u0433\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u00a0Dropwizard \u0442\u0430\u043a\u0436\u0435 \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0441\u00a0SLF4J \u0438 Logback. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043b\u043e\u0433\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435:<\/p>\n<pre><code class=\"java\">import org.slf4j.Logger; import org.slf4j.LoggerFactory;  public class PersonResource {     private static final Logger LOGGER = LoggerFactory.getLogger(PersonResource.class);      @POST     public Response createPerson(Person person) {         LOGGER.info(\"Creating person: {}\", person);         personDB.put(person.getId(), person);         return Response.status(Response.Status.CREATED).entity(person).build();     }      \/\/ \u0414\u0440\u0443\u0433\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f Dropwizard \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c:<\/p>\n<pre><code class=\"java\">import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.annotation.Timed;  public class PersonResource {     private final MetricRegistry metrics;      public PersonResource(MetricRegistry metrics) {         this.metrics = metrics;     }      @POST     @Timed     public Response createPerson(Person person) {         metrics.counter(\"create-person-requests\").inc();         personDB.put(person.getId(), person);         return Response.status(Response.Status.CREATED).entity(person).build();     } }<\/code><\/pre>\n<p>\u042d\u0442\u0430 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f <code>@Timed<\/code> \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u0442\u0435\u043c \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<h2>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430<\/h2>\n<p>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438:<\/p>\n<ul>\n<li>\n<p><strong>\u042e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u044b<\/strong>: \u0422\u0435\u0441\u0442\u0438\u0440\u0443\u044e\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432 \u0438\u0437\u043e\u043b\u044f\u0446\u0438\u0438. \u042e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u044b \u0431\u044b\u0441\u0442\u0440\u044b\u0435 \u0438 \u043f\u0440\u043e\u0441\u0442\u044b \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b<\/strong>: \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u043b\u0438 \u0432\u043d\u0435\u0448\u043d\u0438\u043c API.<\/p>\n<\/li>\n<li>\n<p><strong>\u0422\u0435\u0441\u0442\u044b \u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c<\/strong>: \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443, \u0438 \u0432\u044b\u044f\u0432\u043b\u044f\u044e\u0442 \u0443\u0437\u043a\u0438\u0435 \u043c\u0435\u0441\u0442\u0430 \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u0430. \u0412 Dropwizard \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <strong>JUnit<\/strong> \u0438 <strong>Mockito<\/strong> \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u043e\u0432. \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0435\u0441\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c\u0438 <code>Person<\/code>:<\/p>\n<pre><code class=\"java\">public class PersonService {     private final PersonDAO personDAO;      public PersonService(PersonDAO personDAO) {         this.personDAO = personDAO;     }      public Person findPersonById(long id) {         return personDAO.findById(id).orElseThrow(() -&gt; new NotFoundException(\"Person not found\"));     } }<\/code><\/pre>\n<p>\u042e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"java\">import org.junit.jupiter.api.Test; import org.mockito.Mockito;  import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*;  public class PersonServiceTest {     private final PersonDAO personDAO = Mockito.mock(PersonDAO.class);     private final PersonService personService = new PersonService(personDAO);      @Test     void findPersonById_ShouldReturnPerson_WhenPersonExists() {         Person person = new Person(1, \"John Doe\", 30);         when(personDAO.findById(1L)).thenReturn(Optional.of(person));          Person foundPerson = personService.findPersonById(1L);         assertEquals(\"John Doe\", foundPerson.getName());     }      @Test     void findPersonById_ShouldThrowNotFoundException_WhenPersonDoesNotExist() {         when(personDAO.findById(1L)).thenReturn(Optional.empty());          assertThrows(NotFoundException.class, () -&gt; personService.findPersonById(1L));     } }<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u0442\u0435\u0441\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043a\u0430\u043a \u043f\u043e\u0437\u0438\u0442\u0438\u0432\u043d\u044b\u0435, \u0442\u0430\u043a \u0438 \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u043c\u0435\u0442\u043e\u0434\u0430 <code>findPersonById<\/code>.<\/p>\n<p>Dropwizard \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e Jetty-\u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c REST API, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>Person<\/code> \u043f\u043e ID. \u041c\u043e\u0436\u043d\u043e \u044e\u0437\u0430\u0442\u044c  DropwizardAppRule \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 Dropwizard-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438:<\/p>\n<pre><code class=\"java\">import io.dropwizard.testing.junit5.DropwizardAppExtension; import io.dropwizard.testing.ResourceHelpers; import org.junit.jupiter.api.Test; import static io.restassured.RestAssured.*; import static org.hamcrest.Matchers.*;  public class PersonResourceTest {     private static final DropwizardAppExtension&lt;MyConfiguration&gt; RULE =          new DropwizardAppExtension&lt;&gt;(MyApplication.class, ResourceHelpers.resourceFilePath(\"config-test.yml\"));      @Test     void getPerson_ShouldReturnPerson_WhenPersonExists() {         given()             .when()             .get(\"\/people\/1\")             .then()             .statusCode(200)             .body(\"name\", equalTo(\"John Doe\"));     } }<\/code><\/pre>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>DropwizardAppExtension<\/code>, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0438 <strong>RestAssured<\/strong> \u0434\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0442\u0435\u0441\u0442\u044b \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u0440\u043e\u0439\u0434\u0435\u043d\u044b, \u043f\u043e\u0440\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044e. \u041e\u0434\u0438\u043d \u0438\u0437 \u043b\u0443\u0447\u0448\u0438\u0445 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Docker \u0438 Kubernetes \u0432 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438 \u0441 CI\/CD \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u043e\u043c.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c Dockerfile \u0434\u043b\u044f \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430:<\/p>\n<pre><code>FROM openjdk:11-jre-slim COPY target\/my-application.jar \/app\/my-application.jar WORKDIR \/app CMD [\"java\", \"-jar\", \"my-application.jar\", \"server\", \"config.yml\"]<\/code><\/pre>\n<p>\u0421\u043e\u0431\u0435\u0440\u0435\u043c Docker-\u043e\u0431\u0440\u0430\u0437:<\/p>\n<pre><code class=\"bash\">docker build -t my-application:latest .<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u0432 Kubernetes, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0444\u0430\u0439\u043b \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0430:<\/p>\n<pre><code class=\"yaml\">apiVersion: apps\/v1 kind: Deployment metadata:   name: my-application spec:   replicas: 3   selector:     matchLabels:       app: my-application   template:     metadata:       labels:         app: my-application     spec:       containers:       - name: my-application         image: my-application:latest         ports:         - containerPort: 8080         envFrom:         - configMapRef:             name: my-application-config<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442 \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0435\u0442 3 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0432 Kubernetes.<\/p>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0441 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 \u043c\u043e\u0436\u043d\u043e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f <a href=\"https:\/\/www.dropwizard.io\/en\/stable\/\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<hr\/>\n<p>\u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c \u043f\u0440\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0439 \u0443\u0440\u043e\u043a, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u0442\u043e\u043f \u043e\u0448\u0438\u0431\u043e\u043a \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u0441 \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u0430 \u043d\u0430 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443. \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0432\u0435\u0431\u0438\u043d\u0430\u0440\u0430: <\/p>\n<ul>\n<li>\n<p>\u0412\u044b \u043f\u043e\u0439\u043c\u0435\u0442\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u043d\u0430 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0438 \u043a\u0430\u043a \u0438\u0445 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c.<\/p>\n<\/li>\n<li>\n<p>\u0423\u0437\u043d\u0430\u0435\u0442\u0435 \u043e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430\u0445 \u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u0430\u0445 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0441\u0432\u043e\u0438\u0442\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u044b \u0438 \u043b\u0443\u0447\u0448\u0438\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0445 \u0438 \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u043d\u0430 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u0432\u0430\u043c \u0432 \u0432\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u0417\u0430\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0443\u0440\u043e\u043a \u043c\u043e\u0436\u043d\u043e <a href=\"https:\/\/otus.pw\/pR0Y\/\">\u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043a\u0443\u0440\u0441\u0430 &#171;Microservice Architecture&#187;.<\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/836042\/\"> https:\/\/habr.com\/ru\/articles\/836042\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><em>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440!<\/em><\/p>\n<p><strong>Dropwizard<\/strong>\u00a0\u2014 \u044d\u0442\u043e \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u00a0\u0446\u0435\u043b\u044c\u044e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 RESTful \u0432\u0435\u0431\u2011\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u044f \u0432\u00a0\u0441\u0435\u0431\u0435 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u0445 \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u0412\u00a0\u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u0435 \u043b\u0435\u0436\u0430\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b:<\/p>\n<ul>\n<li>\n<p><strong>Jetty<\/strong>\u00a0\u2014 \u043b\u0435\u0433\u043a\u043e\u0432\u0435\u0441\u043d\u044b\u0439 HTTP \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u043e\u0432, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u0432\u044b\u0441\u043e\u043a\u0443\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u00a0\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p><strong>Jersey<\/strong>\u00a0\u2014 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f RESTful \u0432\u0435\u0431\u2011\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0438 \u043c\u043e\u0449\u043d\u044b\u0439 API \u0434\u043b\u044f\u00a0\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 REST API.<\/p>\n<\/li>\n<li>\n<p><strong>Jackson<\/strong>\u00a0\u2014 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f\u00a0\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 Java \u0432\u00a0JSON \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e, \u0448\u0438\u0440\u043e\u043a\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u0441\u0432\u043e\u0435\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e \u0438 \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c\u044e.<\/p>\n<\/li>\n<li>\n<p><strong>Metrics<\/strong>\u00a0\u2014 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f\u00a0\u0441\u0431\u043e\u0440\u0430 \u0438 \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u043c\u0435\u0442\u0440\u0438\u043a \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0430\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u00a0\u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, Dropwizard \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432\u00a0\u0441\u0435\u0431\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438, \u043b\u043e\u0433\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<h4>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c<\/h4>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441\u00a0\u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430. \u041f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e, \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f JDK,\u00a0\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0435\u0440\u0441\u0438\u0438 11\u00a0\u0438\u043b\u0438\u00a0\u0432\u044b\u0448\u0435. \u0414\u0430\u043b\u0435\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0441\u0431\u043e\u0440\u043a\u0438: <strong>Maven<\/strong> \u0438 <strong>Gradle<\/strong>. \u041e\u0431\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f Dropwizard, \u0438 \u0432\u044b\u0431\u043e\u0440 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u0441\u043a\u043e\u0440\u0435\u0435 \u043e\u0442\u00a0\u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0414\u043b\u044f\u00a0\u0442\u0435\u0445, \u043a\u0442\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u0435\u0442 Maven, \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430. \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 Maven\u2011\u043f\u0440\u043e\u0435\u043a\u0442, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0432 <code>pom.xml<\/code> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438. \u041f\u0440\u0438\u043c\u0435\u0440 \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438:<\/p>\n<pre><code class=\"xml\">&lt;dependency&gt;     &lt;groupId&gt;io.dropwizard&lt;\/groupId&gt;     &lt;artifactId&gt;dropwizard-core&lt;\/artifactId&gt;     &lt;version&gt;2.1.0&lt;\/version&gt; &lt;\/dependency&gt;<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>mvn clean install.<\/code><\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b\u0431\u043e\u0440 \u043f\u0430\u043b Gradle, \u0442\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430 <code>build.gradle<\/code> \u0441\u00a0\u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439:<\/p>\n<pre><code>plugins {     id 'java' }  repositories {     mavenCentral() }  dependencies {     implementation 'io.dropwizard:dropwizard-core:2.1.0' }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>.\/gradlew build<\/code>, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.<\/p>\n<p>\u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u0435\u043d \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c <code>io.dropwizard.Application<\/code> \u0438 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>run<\/code>. \u0412\u043e\u0442 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"java\">public class HelloWorldApplication extends Application&lt;HelloWorldConfiguration&gt; {     public static void main(String[] args) throws Exception {         new HelloWorldApplication().run(args);     }      @Override     public void run(HelloWorldConfiguration configuration, Environment environment) {         final HelloWorldResource resource = new HelloWorldResource(             configuration.getTemplate(),             configuration.getDefaultName()         );         environment.jersey().register(resource);     } }<\/code><\/pre>\n<p>\u041e\u0431\u044b\u0447\u043d\u043e, \u043f\u0440\u043e\u0435\u043a\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d \u043d\u0430\u00a0\u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0447\u0430\u0441\u0442\u0435\u0439:<\/p>\n<ul>\n<li>\n<p><strong>src\/main\/java<\/strong>\u00a0\u2014 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434.<\/p>\n<\/li>\n<li>\n<p><strong>src\/main\/resources<\/strong>\u00a0\u2014 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b, \u0432\u043a\u043b\u044e\u0447\u0430\u044f <code>config.yml<\/code>.<\/p>\n<\/li>\n<li>\n<p><strong>target<\/strong>\u00a0\u2014 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f, \u043a\u0443\u0434\u0430 \u043f\u043e\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b.<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b <code>config.yml<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c \u0432\u00a0\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041f\u0440\u0438\u043c\u0435\u0440 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430:<\/p>\n<pre><code class=\"yaml\">server:   applicationConnectors:     - type: http       port: 8080   adminConnectors:     - type: http       port: 8081  logging:   level: INFO   loggers:     com.example.helloworld: DEBUG<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f, \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0431\u0435\u0437\u00a0\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043a\u043e\u0434.<\/p>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441<\/h2>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e\u00a0\u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c,\u00a0\u2014 \u044d\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c REST API. Dropwizard \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u043c \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0441\u00a0Jersey. \u041d\u0430\u0447\u043d\u0435\u043c \u0441\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 URL\u2011\u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442:<\/p>\n<pre><code class=\"java\">import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType;  @Path(\"\/hello-world\") @Produces(MediaType.APPLICATION_JSON) public class HelloWorldResource {     @GET     public String sayHello() {         return \"{\\\"message\\\":\\\"Hello, World!\\\"}\";     } }<\/code><\/pre>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043a\u043b\u0430\u0441\u0441 <code>HelloWorldResource<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c GET\u2011\u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u043e\u00a0\u043f\u0443\u0442\u0438 <code>\/hello-world<\/code> \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 JSON\u2011\u043e\u0442\u0432\u0435\u0442. \u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 <code>@Path<\/code> \u0438 <code>@GET<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0438 HTTP\u2011\u043c\u0435\u0442\u043e\u0434 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e\u0442 \u0440\u0435\u0441\u0443\u0440\u0441 \u043d\u0430\u0447\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u00a0\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438:<\/p>\n<pre><code class=\"java\">import io.dropwizard.Application; import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment;  public class HelloWorldApplication extends Application&lt;HelloWorldConfiguration&gt; {     public static void main(String[] args) throws Exception {         new HelloWorldApplication().run(args);     }      @Override     public void run(HelloWorldConfiguration configuration, Environment environment) {         final HelloWorldResource resource = new HelloWorldResource();         environment.jersey().register(resource);     } }<\/code><\/pre>\n<p>\u041a\u043b\u0430\u0441\u0441 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u0447\u043a\u043e\u0439 \u0432\u0445\u043e\u0434\u0430 \u0432\u00a0\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0440\u0435\u0441\u0443\u0440\u0441 \u0432\u00a0\u043c\u0435\u0442\u043e\u0434\u0435 <code>run<\/code>, \u0447\u0442\u043e\u0431\u044b Dropwizard \u0437\u043d\u0430\u043b, \u043a\u0430\u043a\u00a0\u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 HTTP\u2011\u0437\u0430\u043f\u0440\u043e\u0441\u044b.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a\u00a0\u0434\u0440\u0443\u0433\u043e\u0439 \u0447\u0430\u0441\u0442\u0438\u00a0\u2014 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 CRUD \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e\u00a0\u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u00a0\u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c\u044e <code>Person<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u043c\u0435\u0435\u0442 ID, \u0438\u043c\u044f \u0438 \u0432\u043e\u0437\u0440\u0430\u0441\u0442:<\/p>\n<pre><code class=\"java\">import com.fasterxml.jackson.annotation.JsonProperty;  public class Person {     private long id;     private String name;     private int age;      public Person() {}      public Person(long id, String name, int age) {         this.id = id;         this.name = name;         this.age = age;     }      @JsonProperty     public long getId() {         return id;     }      @JsonProperty     public String getName() {         return name;     }      @JsonProperty     public int getAge() {         return age;     } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0440\u0435\u0441\u0443\u0440\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u0434\u043b\u044f <code>Person<\/code>:<\/p>\n<pre><code class=\"java\">import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.*;  @Path(\"\/people\") @Produces(MediaType.APPLICATION_JSON) public class PersonResource {     private final Map&lt;Long, Person&gt; personDB = new HashMap&lt;&gt;();      @POST     public Response createPerson(Person person) {         personDB.put(person.getId(), person);         return Response.status(Response.Status.CREATED).entity(person).build();     }      @GET     @Path(\"\/{id}\")     public Person getPerson(@PathParam(\"id\") long id) {         Person person = personDB.get(id);         if (person == null) {             throw new WebApplicationException(\"Person not found\", Response.Status.NOT_FOUND);         }         return person;     }      @PUT     @Path(\"\/{id}\")     public Person updatePerson(@PathParam(\"id\") long id, Person person) {         if (!personDB.containsKey(id)) {             throw new WebApplicationException(\"Person not found\", Response.Status.NOT_FOUND);         }         personDB.put(id, person);         return person;     }      @DELETE     @Path(\"\/{id}\")     public Response deletePerson(@PathParam(\"id\") long id) {         Person person = personDB.remove(id);         if (person == null) {             throw new WebApplicationException(\"Person not found\", Response.Status.NOT_FOUND);         }         return Response.status(Response.Status.NO_CONTENT).build();     } }<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u0440\u0435\u0441\u0443\u0440\u0441 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 CRUD \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u0417\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>HashMap<\/code> \u043a\u0430\u043a\u00a0\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u043e\u00a0\u0432\u00a0\u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u041d\u0435\u00a0\u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043e\u00a0\u0442\u043e\u043c, \u0447\u0442\u043e\u00a0\u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c HTTP\u2011\u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442\u044b. \u0412\u00a0\u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u043c \u0432\u044b\u0448\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442 <code>Response<\/code> \u0434\u043b\u044f\u00a0\u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0443\u0441\u0430\u043c\u0438 HTTP \u0438 \u0442\u0435\u043b\u043e\u043c \u043e\u0442\u0432\u0435\u0442\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <code>Person<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u0442\u0443\u0441 <code>201 Created<\/code>, \u0447\u0442\u043e\u00a0\u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u00a0\u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>@PathParam<\/code> \u0434\u043b\u044f\u00a0\u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0438\u0437\u00a0URL, \u0430 <code>@JsonProperty<\/code> \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432\u00a0JSON \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0432\u00a0\u0432\u0438\u0437\u0430\u0440\u0434\u0435 \u0435\u0441\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f\u00a0\u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 <code>@NotNull<\/code>, <code>@Size<\/code>, <code>@Min<\/code>, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e\u00a0\u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c \u043f\u0435\u0440\u0435\u0434 \u0438\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438:<\/p>\n<pre><code class=\"java\">import javax.validation.constraints.Min; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull;  public class Person {     private long id;      @NotEmpty     private String name;      @Min(0)     private int age;      \/\/ \u0413\u0435\u0442\u0442\u0435\u0440\u044b \u0438 \u0441\u0435\u0442\u0442\u0435\u0440\u044b }<\/code><\/pre>\n<p>\u041b\u043e\u0433\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u00a0Dropwizard \u0442\u0430\u043a\u0436\u0435 \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0441\u00a0SLF4J \u0438 Logback. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043b\u043e\u0433\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435:<\/p>\n<pre><code class=\"java\">import org.slf4j.Logger; import org.slf4j.LoggerFactory;  public class PersonResource {     private static final Logger LOGGER = LoggerFactory.getLogger(PersonResource.class);      @POST     public Response createPerson(Person person) {         LOGGER.info(\"Creating person: {}\", person);         personDB.put(person.getId(), person);         return Response.status(Response.Status.CREATED).entity(person).build();     }      \/\/ \u0414\u0440\u0443\u0433\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f Dropwizard \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c:<\/p>\n<pre><code class=\"java\">import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.annotation.Timed;  public class PersonResource {     private final MetricRegistry metrics;      public PersonResource(MetricRegistry metrics) {         this.metrics = metrics;     }      @POST     @Timed     public Response createPerson(Person person) {         metrics.counter(\"create-person-requests\").inc();         personDB.put(person.getId(), person);         return Response.status(Response.Status.CREATED).entity(person).build();     } }<\/code><\/pre>\n<p>\u042d\u0442\u0430 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f <code>@Timed<\/code> \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u0442\u0435\u043c \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<h2>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430<\/h2>\n<p>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438:<\/p>\n<ul>\n<li>\n<p><strong>\u042e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u044b<\/strong>: \u0422\u0435\u0441\u0442\u0438\u0440\u0443\u044e\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432 \u0438\u0437\u043e\u043b\u044f\u0446\u0438\u0438. \u042e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u044b \u0431\u044b\u0441\u0442\u0440\u044b\u0435 \u0438 \u043f\u0440\u043e\u0441\u0442\u044b \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b<\/strong>: \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u043b\u0438 \u0432\u043d\u0435\u0448\u043d\u0438\u043c API.<\/p>\n<\/li>\n<li>\n<p><strong>\u0422\u0435\u0441\u0442\u044b \u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c<\/strong>: \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443, \u0438 \u0432\u044b\u044f\u0432\u043b\u044f\u044e\u0442 \u0443\u0437\u043a\u0438\u0435 \u043c\u0435\u0441\u0442\u0430 \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u0430. \u0412 Dropwizard \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <strong>JUnit<\/strong> \u0438 <strong>Mockito<\/strong> \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u043e\u0432. \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0435\u0441\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c\u0438 <code>Person<\/code>:<\/p>\n<pre><code class=\"java\">public class PersonService {     private final PersonDAO personDAO;      public PersonService(PersonDAO personDAO) {<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-429742","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/429742","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=429742"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/429742\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=429742"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=429742"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=429742"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}