{"id":160281,"date":"2012-11-26T16:53:03","date_gmt":"2012-11-26T12:53:03","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=160281"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=160281","title":{"rendered":"<span class=\"post_title\">\u0412\u0435\u0431 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441 Gaelyk<\/span>"},"content":{"rendered":"<div class=\"content html_format\">   \t\u041c\u0435\u043d\u044f \u0434\u0430\u0432\u043d\u043e \u0432\u043e\u043f\u0440\u043e\u0441 \u2014 \u043d\u0430 \u0447\u0451\u043c \u043f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0435\u0431 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u044f\u0432\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0443 \u043d\u0435\u0438\u0441\u043a\u0443\u0448\u0435\u043d\u043d\u043e\u043c\u0443 \u0432 \u0432\u0435\u0431 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435.<\/p>\n<p>  \u041c\u0435\u043d\u044f \u0441\u043c\u0443\u0449\u0430\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0449\u0435\u0439 \u2014 \u0432\u043e \u043f\u0435\u0440\u0432\u044b\u0445 \u2014 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043b\u043e\u0433\u0438\u043d, \u043f\u0440\u0430\u0432\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u041d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441 \u044d\u0442\u0438\u043c \u043c\u043d\u043e\u0433\u043e \u0432\u043e\u0437\u0438\u0442\u044c\u0441\u044f. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u0437\u0434\u0435\u0441\u044c \u044f \u043d\u0430\u0448\u0435\u043b \u0432 Grails \u0441 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u043c Spring Security.<\/p>\n<p>  \u0412\u043e \u0432\u0442\u043e\u0440\u044b\u0445 \u2014 \u0445\u043e\u0441\u0442\u0438\u043d\u0433. \u0415\u0441\u043b\u0438 \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 \u042f\u0432\u0435 (\u0430 \u043c\u043d\u0435 \u0442\u0430\u043a \u043a\u043e\u043c\u0444\u043e\u0440\u0442\u043d\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u044f \u043d\u0430 \u042f\u0432\u0435 \u0441 1996 \u0433\u043e\u0434\u0430), \u0442\u043e \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043e\u0440\u043e\u0433\u043e\u0439. \u041f\u043b\u0430\u0442\u0438\u0442\u044c \u043f\u043e 15-20 \u0434\u043e\u043b\u043b\u0430\u0440\u043e\u0432 \u0432 \u043c\u0435\u0441\u044f\u0446 \u0437\u0430 \u0441\u0430\u0439\u0442\u044b-\u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u044b \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c.<\/p>\n<p>  \u0418 \u0432\u043e\u0442, \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u044f \u043d\u0430\u0448\u0435\u043b \u0440\u0435\u0448\u0435\u043d\u0438\u0435. \u042d\u0442\u043e \u2014 <a href=\"http:\/\/gaelyk.appspot.com\/\">Gaelyk<\/a>. Groovy \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f Google App Engine.<\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c \u0447\u0442\u043e \u043e\u043d \u0434\u0430\u0451\u0442 \u0438 \u043a\u0430\u043a \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<p>  \u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043a\u0430\u0447\u0430\u0432 <a href=\"http:\/\/gaelyk.appspot.com\/tutorial\/template-project\">template project<\/a> \u0438\u043b\u0438 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0432\u0448\u0438\u0441\u044c <a href=\"http:\/\/code.google.com\/p\/maven-gaelyk\/\">maven archetype<\/a><\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u0436\u0435 \u043f\u0435\u0440\u0432\u044b\u0439 \u0438\u0437 \u043d\u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 gradle, \u0430 \u043d\u0435 maven \u0438 \u043e\u0431\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 groovy \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440, \u0430 \u043d\u0435 \u044d\u043a\u0441\u043b\u0438\u043f\u0441\u043e\u0432\u0441\u043a\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0431\u044b, \u0438 \u043e\u0431\u0430 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Google datastore<\/p>\n<p>  \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u0441\u0432\u043e\u0439 maven archetype. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0438 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c Gaelyk \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<p>  <a name=\"habracut\"><\/a><\/p>\n<pre><code>mvn archetype:generate -DarchetypeGroupId=org.bernshtam -DarchetypeArtifactId=gaelyk-archetype -DarchetypeRepository=http:\/\/bernshtam.name\/maven2 -DgroupId=myexample -DartifactId=test1 -DarchetypeVersion=1.0 <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u043c\u043f\u043e\u0440\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u0432 IDEA (\u0432 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0438\u0437 \u0430\u0440\u0445\u0435\u0442\u0430\u0439\u043f\u0430 \u043c\u043e\u0436\u043d\u043e \u0432 IDEA \u0442\u043e\u0436\u0435):<\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u0430 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c Facet Google App Engine:<\/p>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage2\/0bc\/bce\/617\/0bcbce61746bbfcc88c55ca8f2c48321.jpg\"\/><\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0437\u0430\u043f\u0443\u0441\u043a\u0430.<br \/>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0447\u0442\u043e Google App Engine development kit, \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0443\u0436\u0435 \u0438\u043d\u0441\u0442\u0430\u043b\u043b\u0438\u0440\u043e\u0432\u0430\u043d \u0443 \u0412\u0430\u0441 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0435 \u0438 \u0443\u043a\u0430\u0437\u0430\u043d \u0432 IDEA (\u044f \u0443\u043a\u0430\u0437\u0430\u043b \u043a\u043d\u043e\u043f\u043a\u0443). \u0412\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u043d\u0435\u0441\u0435\u0442 maven.<\/p>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage2\/950\/484\/c02\/950484c02da8eacb6b3912f6c45569a5.jpg\"\/><\/p>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage2\/3bc\/819\/7e2\/3bc8197e26d345a58ef5e1c976e38e81.jpg\"\/><\/p>\n<p>  \u041d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043c\u0430\u0432\u0435\u043d\u043e\u0432\u0441\u043a\u0438\u0439 install:<\/p>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage2\/20d\/99d\/5e6\/20d99d5e6fd16e83f2ccc9e8879a86ff.jpg\"\/><\/p>\n<p>  \u0418 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c!<\/p>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage2\/fb1\/919\/6c6\/fb19196c695494e469339dde3a3b8c20.jpg\"\/><\/p>\n<p>  \u0423\u0440\u0430, \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442! \u042d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043c\u0435\u0442\u043e\u043a \u0441 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c (\u0437\u0430\u0447\u0435\u043c \u0437\u0430\u043c\u0435\u0442\u043a\u0430\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u2014 \u044f \u043d\u0435 \u0437\u043d\u0430\u044e \ud83d\ude42 )<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u0436\u0435 \u0442\u0430\u043c \u0435\u0441\u0442\u044c.<\/p>\n<p>  web.xml \u0441\u0442\u0430\u0432\u0438\u0442 \u0441\u0435\u0440\u0432\u043b\u0435\u0442 \u0434\u043b\u044f \u0433\u0440\u0443\u0432\u043b\u0435\u0442\u043e\u0432 \u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 (gtpl)<\/p>\n<pre><code class=\"xml\">&lt;web-app xmlns=&quot;http:\/\/java.sun.com\/xml\/ns\/javaee&quot; version=&quot;2.5&quot;&gt;     &lt;listener&gt;         &lt;listener-class&gt;groovyx.gaelyk.GaelykServletContextListener&lt;\/listener-class&gt;     &lt;\/listener&gt;      &lt;servlet&gt;         &lt;servlet-name&gt;GroovletServlet&lt;\/servlet-name&gt;         &lt;servlet-class&gt;groovyx.gaelyk.GaelykServlet&lt;\/servlet-class&gt;         &lt;init-param&gt;             &lt;param-name&gt;verbose&lt;\/param-name&gt;             &lt;!-- Set it to true for more details --&gt;             &lt;param-value&gt;false&lt;\/param-value&gt;         &lt;\/init-param&gt;         &lt;load-on-startup&gt;1&lt;\/load-on-startup&gt;     &lt;\/servlet&gt;     &lt;servlet&gt;         &lt;servlet-name&gt;TemplateServlet&lt;\/servlet-name&gt;         &lt;servlet-class&gt;groovyx.gaelyk.GaelykTemplateServlet&lt;\/servlet-class&gt;         &lt;init-param&gt;             &lt;!-- Remove the default &quot;generated by&quot; messages from the templates --&gt;             &lt;param-name&gt;generated.by&lt;\/param-name&gt;             &lt;param-value&gt;false&lt;\/param-value&gt;         &lt;\/init-param&gt;         &lt;init-param&gt;             &lt;param-name&gt;verbose&lt;\/param-name&gt;             &lt;!-- Output generation time in the HTML, see source page --&gt;             &lt;param-value&gt;false&lt;\/param-value&gt;         &lt;\/init-param&gt;         &lt;load-on-startup&gt;1&lt;\/load-on-startup&gt;     &lt;\/servlet&gt;      &lt;filter&gt;         &lt;filter-name&gt;RoutesFilter&lt;\/filter-name&gt;         &lt;filter-class&gt;groovyx.gaelyk.routes.RoutesFilter&lt;\/filter-class&gt;     &lt;\/filter&gt;      &lt;servlet-mapping&gt;         &lt;servlet-name&gt;GroovletServlet&lt;\/servlet-name&gt;         &lt;url-pattern&gt;*.groovy&lt;\/url-pattern&gt;     &lt;\/servlet-mapping&gt;     &lt;servlet-mapping&gt;         &lt;servlet-name&gt;TemplateServlet&lt;\/servlet-name&gt;         &lt;url-pattern&gt;*.gtpl&lt;\/url-pattern&gt;     &lt;\/servlet-mapping&gt;      &lt;filter-mapping&gt;         &lt;filter-name&gt;RoutesFilter&lt;\/filter-name&gt;         &lt;url-pattern&gt;\/*&lt;\/url-pattern&gt;     &lt;\/filter-mapping&gt;      &lt;welcome-file-list&gt;         &lt;welcome-file&gt;index.gtpl&lt;\/welcome-file&gt;     &lt;\/welcome-file-list&gt; &lt;\/web-app&gt; <\/code><\/pre>\n<p>  appengine-web.xml \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u0434\u043b\u044f Google App Engine. \u0412\u0430\u043c \u043d\u0430\u0434\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c test1-archetype \u043d\u0430 \u0438\u043c\u044f \u0441\u0432\u043e\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f app engine, \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 app engine<\/p>\n<pre><code class=\"xml\">&lt;appengine-web-app xmlns=&quot;http:\/\/appengine.google.com\/ns\/1.0-SNAPSHOT&quot;&gt;     &lt;application&gt;test1-archetype&lt;\/application&gt;          &lt;version&gt;1&lt;\/version&gt;      &lt;!-- Enable concurrent requests by default to serve requests in parallel --&gt;     &lt;threadsafe&gt;true&lt;\/threadsafe&gt;      &lt;!-- If all your templates and groovlets are encoding in UTF-8 --&gt;     &lt;!-- Please specify the settings below, otherwise weird characters may appear in your templates --&gt;     &lt;system-properties&gt;         &lt;property name=&quot;file.encoding&quot; value=&quot;UTF-8&quot;\/&gt;         &lt;property name=&quot;groovy.source.encoding&quot; value=&quot;UTF-8&quot;\/&gt;         &lt;property name=&quot;java.util.logging.config.file&quot; value=&quot;WEB-INF\/logging.properties&quot; \/&gt;     &lt;\/system-properties&gt;      &lt;!-- Uncomment this section if you want your application to be able to receive XMPP messages --&gt;     &lt;!-- And create a file named jabber.groovy in \/WEB-INF\/groovy --&gt;     &lt;!-- Similarily, if you want to receive incoming emails --&gt;     &lt;!-- And create a file named email.groovy in \/WEB-INF\/groovy --&gt;     &lt;!--     &lt;inbound-services&gt;         &lt;service&gt;xmpp_message&lt;\/service&gt;         &lt;service&gt;mail&lt;\/service&gt;     &lt;\/inbound-services&gt;     --&gt;      &lt;!-- It it advised to keep this parameter to true --&gt;     &lt;!-- as per the release of SDK 1.2.8, --&gt;     &lt;!-- this should speed up cold startups of applications by 10% --&gt;     &lt;precompilation-enabled&gt;true&lt;\/precompilation-enabled&gt;          &lt;static-files&gt;         &lt;exclude path=&quot;\/WEB-INF\/**.groovy&quot; \/&gt;         &lt;exclude path=&quot;**.gtpl&quot; \/&gt;     &lt;\/static-files&gt; &lt;\/appengine-web-app&gt;  <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430 Gaelyk. routes.groovy \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043a\u0430\u043a\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043a\u0443\u0434\u0430 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c<\/p>\n<pre><code>get &quot;\/&quot;, redirect: &quot;listnotes.groovy&quot; get &quot;\/favicon.ico&quot;, redirect: &quot;\/images\/favicon.png&quot; <\/code><\/pre>\n<p>  Gaelyk \u044d\u0442\u043e MVC \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0431\u0443\u0434\u0443\u0442 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b, \u0432 \u0440\u043e\u043b\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0442\u0443\u0442 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u044e\u0442 \u0433\u0440\u0443\u0432\u043b\u0435\u0442\u044b. \u041f\u043e\u043b\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 DSL \u0434\u043b\u044f routes.groovy \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"http:\/\/gaelyk.appspot.com\/tutorial\/url-routing\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043a\u043b\u0430\u0441\u0441 Note:<\/p>\n<pre><code>package myexample  import groovyx.gaelyk.datastore.Entity import groovyx.gaelyk.datastore.Key import groovyx.gaelyk.datastore.Unindexed  @Entity(unindexed=false) class Note {     @Key long id     String login     @Unindexed int priority     String text } <\/code><\/pre>\n<p>  \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e Gaelyk \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0443\u044e \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e \u0441 Google App Engine datastore \u2014 \u044d\u0442\u043e \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 ORM, \u043d\u0435 JPA, \u043d\u043e \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0445 \u0432\u0435\u0449\u0435\u0439 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442.<\/p>\n<p>  \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0432 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430\u0445:<\/p>\n<pre><code> Note  note = new Note(priority:priority, text: text, login: email) note.save() ...  def  note = Note.get(id) note.delete() .. def notes = Note.findAll { login == email } <\/code><\/pre>\n<p>  \u042d\u043b\u0435\u0433\u0430\u043d\u0442\u043d\u043e, \u043d\u0435 \u043f\u0440\u0430\u0432\u0434\u0430 \u043b\u0438?<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u043d\u0430 \u044d\u0442\u043e:  <\/p>\n<pre><code>def email = user.email ... log.fine(&quot;$notes ${notes.size()}&quot;) ... String text =   request.getParameter(&quot;text&quot;) <\/code><\/pre>\n<p>  \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 user, request \u0438 log \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b. \u041e\u043d\u0438 \u0438\u043d\u0436\u0435\u043a\u0442\u044f\u0442\u0441\u044f, \u043a\u0430\u043a \u0438 \u043c\u043d\u043e\u0433\u0438\u0435 \u0434\u0440\u0443\u0433\u0438\u0435. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 user \u0431\u0443\u0434\u0435\u0442 null, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u043b \u043b\u043e\u0433\u0438\u043d \u0438 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0434\u0435\u0442\u0430\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0435\u0441\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u043b. log \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043b\u043e\u0433\u0433\u0435\u0440.<br \/>  request \u2014 \u044d\u0442\u043e HttpRequest<\/p>\n<p>  \u0412\u043e\u043e\u0431\u0449\u0435,<a href=\"http:\/\/gaelyk.appspot.com\/tutorial\/views-and-controllers#variables\"> \u0432\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u0443\u0434\u0438\u0432\u043b\u0435\u043d\u044b \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0435\u0433\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u043d\u0436\u0435\u043a\u0442\u0438\u0442\u0441\u044f<\/a> \u0432 \u0412\u0430\u0448\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b \u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u044b (\u0430 \u043f\u043e \u0436\u0435\u043b\u0430\u043d\u0438\u044e \u2014 \u0438 \u0432 \u043b\u044e\u0431\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b)<\/p>\n<p>  \u041c\u043e\u0434\u0435\u043b\u044c \u0438\u0437 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432 \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 request:  <\/p>\n<pre><code> request['notes'] = notes forward &quot;index.gtpl&quot; <\/code><\/pre>\n<p>  \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u044b. \u041e\u043d\u0438 \u043f\u043e\u0445\u043e\u0436\u0438 \u043d\u0430 jsp, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 % include %, \u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u043a\u043e\u0434\u0430  <\/p>\n<pre><code>&lt;% include '\/WEB-INF\/includes\/header.gtpl' %&gt;  &lt;h1&gt;My notes&lt;\/h1&gt;  &lt;% if (user) { %&gt;     &lt;p&gt;                &lt;table width=&quot;50%&quot; border=&quot;1&quot;&gt;                 &lt;tr&gt;&lt;th width=&quot;30%&quot;&gt;Note&lt;\/th&gt;&lt;th&gt;Priority&lt;\/th&gt;&lt;th&gt;&lt;\/th&gt;&lt;\/tr&gt;                     &lt;% request.notes.each { note -&gt; %&gt;                         &lt;tr&gt;&lt;td&gt;${note.text}&lt;\/td&gt;&lt;td align=&quot;left&quot;&gt; ${note.priority}&lt;\/td&gt;&lt;td&gt;&lt;A href=&quot;deletenote.groovy?id=${note.id}&quot;&gt;X&lt;\/A&gt; &lt;\/td&gt;&lt;\/tr&gt;                     &lt;% } %&gt;             &lt;\/table&gt;       &lt;\/p&gt;     &lt;div class=&quot;add&quot;&gt;     &lt;h2&gt;Add a new note&lt;\/h2&gt;     &lt;p&gt;     &lt;form name=&quot;addnote&quot; action=&quot;addnote.groovy&quot; method=&quot;post&quot;&gt;      Priority: &lt;input name=&quot;priority&quot; id=&quot;priority&quot; type=&quot;number&quot; value=&quot;1&quot; min=&quot;1&quot; max=&quot;10&quot;\/&gt;&lt;br\/&gt; &lt;br\/&gt;     Text: &lt;input name=&quot;text&quot; id=&quot;text&quot; type=&quot;text&quot;\/&gt;     &lt;input type=&quot;submit&quot; value=&quot; Add Note &quot;\/&gt;&lt;\/form&gt;     &lt;\/p&gt;     &lt;\/div&gt;     &lt;% } else { %&gt;     &lt;p&gt;&lt;A href=&quot;${users.createLoginURL(&quot;\/&quot;)}&quot;&gt;Login&lt;\/A&gt; &lt;\/p&gt; to access your notes &lt;% } %&gt;   &lt;% include '\/WEB-INF\/includes\/footer.gtpl' %&gt;  <\/code><\/pre>\n<p>  \u0417\u0430\u043c\u0435\u0442\u044c\u0442\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0437\u0430\u043b\u043e\u0433\u0438\u043d\u0438\u043b\u0441\u044f ( <code>if (user)<\/code>), \u0432\u044b\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0437 request ( <code>request.notes.each<\/code> ), \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0433\u0440\u0443\u0432\u0438 \u0441\u0442\u0438\u043b\u044f <code>${note.priority}<\/code>, \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u043b\u043e\u0433\u0438\u043d: <code>${users.createLoginURL(&quot;\/&quot;)}<\/code> (users \u2014 \u0435\u0449\u0435 \u043e\u0434\u043d\u0430 \u0438\u043d\u0436\u0435\u043a\u0442\u043d\u0443\u0442\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f).<\/p>\n<p>  \u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441 \u043b\u043e\u0433\u0438\u043d\u043e\u043c \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435 \u0442\u0430\u043a, \u043a\u0430\u043a \u043f\u043e\u0441\u043b\u0435 \u0434\u0435\u043f\u043b\u043e\u0439\u043c\u0435\u043d\u0442\u0430 \u043d\u0430 Google App Engine, \u043e\u043d\u0430 \u0434\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043b\u043e\u0433\u0438\u043d\u0438\u0442\u0441\u044f \u043f\u043e\u0434 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0430\u0434\u0440\u0435\u0441\u0430\u043c\u0438, \u043a\u0430\u043a \u0430\u0434\u043c\u0438\u043d \u0438 \u043d\u0435 \u043a\u0430\u043a \u0430\u0434\u043c\u0438\u043d<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u043e\u0441\u044c, \u043d\u0430\u0447\u0438\u043d\u0430\u0439\u0442\u0435 \u0447\u0438\u0442\u0430\u0442\u044c <a href=\"http:\/\/gaelyk.appspot.com\/tutorial\/\">tutorial<\/a>    \t   \t<\/p>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/160281\/\"> http:\/\/habrahabr.ru\/post\/160281\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">   \t\u041c\u0435\u043d\u044f \u0434\u0430\u0432\u043d\u043e \u0432\u043e\u043f\u0440\u043e\u0441 \u2014 \u043d\u0430 \u0447\u0451\u043c \u043f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0435\u0431 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u044f\u0432\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0443 \u043d\u0435\u0438\u0441\u043a\u0443\u0448\u0435\u043d\u043d\u043e\u043c\u0443 \u0432 \u0432\u0435\u0431 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435.<\/p>\n<p>  \u041c\u0435\u043d\u044f \u0441\u043c\u0443\u0449\u0430\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0449\u0435\u0439 \u2014 \u0432\u043e \u043f\u0435\u0440\u0432\u044b\u0445 \u2014 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043b\u043e\u0433\u0438\u043d, \u043f\u0440\u0430\u0432\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u041d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441 \u044d\u0442\u0438\u043c \u043c\u043d\u043e\u0433\u043e \u0432\u043e\u0437\u0438\u0442\u044c\u0441\u044f. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u0437\u0434\u0435\u0441\u044c \u044f \u043d\u0430\u0448\u0435\u043b \u0432 Grails \u0441 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u043c Spring Security.<\/p>\n<p>  \u0412\u043e \u0432\u0442\u043e\u0440\u044b\u0445 \u2014 \u0445\u043e\u0441\u0442\u0438\u043d\u0433. \u0415\u0441\u043b\u0438 \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 \u042f\u0432\u0435 (\u0430 \u043c\u043d\u0435 \u0442\u0430\u043a \u043a\u043e\u043c\u0444\u043e\u0440\u0442\u043d\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u044f \u043d\u0430 \u042f\u0432\u0435 \u0441 1996 \u0433\u043e\u0434\u0430), \u0442\u043e \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043e\u0440\u043e\u0433\u043e\u0439. \u041f\u043b\u0430\u0442\u0438\u0442\u044c \u043f\u043e 15-20 \u0434\u043e\u043b\u043b\u0430\u0440\u043e\u0432 \u0432 \u043c\u0435\u0441\u044f\u0446 \u0437\u0430 \u0441\u0430\u0439\u0442\u044b-\u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u044b \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c.<\/p>\n<p>  \u0418 \u0432\u043e\u0442, \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u044f \u043d\u0430\u0448\u0435\u043b \u0440\u0435\u0448\u0435\u043d\u0438\u0435. \u042d\u0442\u043e \u2014 <a href=\"http:\/\/gaelyk.appspot.com\/\">Gaelyk<\/a>. Groovy \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f Google App Engine.<\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c \u0447\u0442\u043e \u043e\u043d \u0434\u0430\u0451\u0442 \u0438 \u043a\u0430\u043a \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<p>  \u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043a\u0430\u0447\u0430\u0432 <a href=\"http:\/\/gaelyk.appspot.com\/tutorial\/template-project\">template project<\/a> \u0438\u043b\u0438 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0432\u0448\u0438\u0441\u044c <a href=\"http:\/\/code.google.com\/p\/maven-gaelyk\/\">maven archetype<\/a><\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u0436\u0435 \u043f\u0435\u0440\u0432\u044b\u0439 \u0438\u0437 \u043d\u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 gradle, \u0430 \u043d\u0435 maven \u0438 \u043e\u0431\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 groovy \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440, \u0430 \u043d\u0435 \u044d\u043a\u0441\u043b\u0438\u043f\u0441\u043e\u0432\u0441\u043a\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0431\u044b, \u0438 \u043e\u0431\u0430 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Google datastore<\/p>\n<p>  \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u0441\u0432\u043e\u0439 maven archetype. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0438 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c Gaelyk \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\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-160281","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/160281","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=160281"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/160281\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=160281"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=160281"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=160281"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}