📜 ⬆️ ⬇️

Web development with Gaelyk

I have long been concerned with the question - what is the easiest way to make a web application Java programmer inexperienced in web development.

I was confused by a few things - firstly, user registration, login, access rights, and so on. I did not want to mess around with it a lot. I found the solution here in Grails with the Spring Security plugin.

Secondly - hosting. If you write in Java (and I feel most comfortable, I have been in Java since 1996), then hosting is expensive. Pay for 15-20 dollars a month for sites-experiments did not want to.
')
And finally, I found a solution. This is Gaelyk . Groovy framework for google app engine.

To understand what it gives and how to use it, let's look at the simplest project.

The simplest project can be done by downloading a template project or using maven archetype

However, the first one uses gradle, not maven, and both use the standard groovy compiler, not the Exlipsovsky, which allows you not to create stubs, and both do not create an example of working with Google datastore

So I created my maven archetype. Let's use it and create a Gaelyk project:



mvn archetype:generate -DarchetypeGroupId=org.bernshtam -DarchetypeArtifactId=gaelyk-archetype -DarchetypeRepository=http://bernshtam.name/maven2 -DgroupId=myexample -DartifactId=test1 -DarchetypeVersion=1.0 


Now you can import the created project into IDEA (in principle, you can generate a project from archetype in IDEA too):

After the import, it remains to add the Facet Google App Engine:



After that we add a launch configuration.
Please note that the Google App Engine development kit should already be installed on your machine and listed in IDEA (I have indicated the button). All other dependencies will bring maven.





Click on mavenovsky install:



And run!



Hurray, it works! This is the simplest application for creating notes with priority (why priorities are notes - I don’t know :))

Now let's see what is there.

web.xml installs a servlet for grooves and templates (gtpl)

 <web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5"> <listener> <listener-class>groovyx.gaelyk.GaelykServletContextListener</listener-class> </listener> <servlet> <servlet-name>GroovletServlet</servlet-name> <servlet-class>groovyx.gaelyk.GaelykServlet</servlet-class> <init-param> <param-name>verbose</param-name> <!-- Set it to true for more details --> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>TemplateServlet</servlet-name> <servlet-class>groovyx.gaelyk.GaelykTemplateServlet</servlet-class> <init-param> <!-- Remove the default "generated by" messages from the templates --> <param-name>generated.by</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>verbose</param-name> <!-- Output generation time in the HTML, see source page --> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <filter> <filter-name>RoutesFilter</filter-name> <filter-class>groovyx.gaelyk.routes.RoutesFilter</filter-class> </filter> <servlet-mapping> <servlet-name>GroovletServlet</servlet-name> <url-pattern>*.groovy</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>TemplateServlet</servlet-name> <url-pattern>*.gtpl</url-pattern> </servlet-mapping> <filter-mapping> <filter-name>RoutesFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.gtpl</welcome-file> </welcome-file-list> </web-app> 


appengine-web.xml descriptor for Google App Engine. You need to replace test1-archetype with the name of your app engine application previously created in the app engine console.

 <appengine-web-app xmlns="http://appengine.google.com/ns/1.0-SNAPSHOT"> <application>test1-archetype</application> <version>1</version> <!-- Enable concurrent requests by default to serve requests in parallel --> <threadsafe>true</threadsafe> <!-- If all your templates and groovlets are encoding in UTF-8 --> <!-- Please specify the settings below, otherwise weird characters may appear in your templates --> <system-properties> <property name="file.encoding" value="UTF-8"/> <property name="groovy.source.encoding" value="UTF-8"/> <property name="java.util.logging.config.file" value="WEB-INF/logging.properties" /> </system-properties> <!-- Uncomment this section if you want your application to be able to receive XMPP messages --> <!-- And create a file named jabber.groovy in /WEB-INF/groovy --> <!-- Similarily, if you want to receive incoming emails --> <!-- And create a file named email.groovy in /WEB-INF/groovy --> <!-- <inbound-services> <service>xmpp_message</service> <service>mail</service> </inbound-services> --> <!-- It it advised to keep this parameter to true --> <!-- as per the release of SDK 1.2.8, --> <!-- this should speed up cold startups of applications by 10% --> <precompilation-enabled>true</precompilation-enabled> <static-files> <exclude path="/WEB-INF/**.groovy" /> <exclude path="**.gtpl" /> </static-files> </appengine-web-app> 


Now the specifics of Gaelyk. routes.groovy contains instructions which request to redirect

 get "/", redirect: "listnotes.groovy" get "/favicon.ico", redirect: "/images/favicon.png" 


Gaelyk is an MVC framework, which means that requests will most often be redirected to controllers, in the role of which there are grooves. A full description of DSL for routes.groovy can be found here .

Now look at the Note class:

 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 } 


By default, Gaelyk offers the simplest integration with Google App Engine datastore - this is not a full-fledged ORM, not JPA, but it is suitable for the simplest things.

You can see examples in the controllers:

 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 } 


Elegant, isn't it?

Now look at this:
 def email = user.email ... log.fine("$notes ${notes.size()}") ... String text = request.getParameter("text") 


The variables user, request and log are not defined. They are injected, like many others. In particular, user will be null if the user has not made a login and will contain a class containing user details if made. log contains a logger.
request is HttpRequest

In general, you will be surprised how much everything is automatically injected into your controllers and templates (and, if desired, into any classes)

The model from the controllers to the templates is passed through the request properties:
 request['notes'] = notes forward "index.gtpl" 


It remains to look at the templates. They are similar to jsp, contain% include%, code inserts
 <% include '/WEB-INF/includes/header.gtpl' %> <h1>My notes</h1> <% if (user) { %> <p> <table width="50%" border="1"> <tr><th width="30%">Note</th><th>Priority</th><th></th></tr> <% request.notes.each { note -> %> <tr><td>${note.text}</td><td align="left"> ${note.priority}</td><td><A href="deletenote.groovy?id=${note.id}">X</A> </td></tr> <% } %> </table> </p> <div class="add"> <h2>Add a new note</h2> <p> <form name="addnote" action="addnote.groovy" method="post"> Priority: <input name="priority" id="priority" type="number" value="1" min="1" max="10"/><br/> <br/> Text: <input name="text" id="text" type="text"/> <input type="submit" value=" Add Note "/></form> </p> </div> <% } else { %> <p><A href="${users.createLoginURL("/")}">Login</A> </p> to access your notes <% } %> <% include '/WEB-INF/includes/footer.gtpl' %> 


Notice the check that the user has logged in ( if (user) ), pulling the model out of request ( request.notes.each ), using the ${note.priority} style ${note.priority} , creating a login link: ${users.createLoginURL("/")} (users - another injected variable).

The page with the login in the development does not look at all like after the deployment on Google App Engine, it gives the opportunity to login under different addresses, like the admin and not as the admin

If you like it, start reading the tutorial

Source: https://habr.com/ru/post/160281/


All Articles