1. Grails
Grails là một "web framework" phát triển trên nền ngôn ngữ
Groovy và Java mà có thể deployed vào "Java web servers" đã tồn tại như
Tomcat hoặc
Jetty.
Grails cho phép tạo nhanh "web applications"; nó có khả năng làm mới một dự án trong vài phút. Grails là dựa trên ý tưởng "convention over configuration" mà cho phép ứng dụng tự động sinh ra dựa trên naming schemes (thay vì sử dụng configuration files, e.gl XML files).
The Grails framework cho phép phát triển mà không đòi hỏi cấu hình. Chỉ cần Grails và bạn đã sẵn sàng. Grails thực hiện tự động các "Tomcat webcontainer" và HSQLDB database trong suốt quá trình development. Nếu bạn triển khai ứng dụng Grails sau đó bạn có thể sử dụng webcontainer hoặc database khác.
Grails sử dụng GORM (Grails Object Relational Mapping) cho sự tồn tại của domain model. GORM là dựa trên Hibernate. Bạn có thể test với HSQLDB và run in production đối với database đơn giản khác bằng cách thay đổi tập tin cấu hình (DataSource.groovy).
Grails sử dụng JavaEE làm kiến trúc cơ bản và Spring để cấu trúc ứng dụng với dependency injection.
Grails là plug-in dựa vào và cung cấp sở hữu build system riêng (Gant). The Grails homepage cung cấp một vài pre-defined plugins để mở rộng Grails framework.
Trong thời gian bắt đầu một phát triển mới với Grails bạn chủ yếu sử dụng command line để tạo ra giao diện người dùng mới.
Grails cho phép tạo nhanh "web applications"; nó có khả năng làm mới một dự án trong vài phút. Grails là dựa trên ý tưởng "convention over configuration" mà cho phép ứng dụng tự động sinh ra dựa trên naming schemes (thay vì sử dụng configuration files, e.gl XML files).
The Grails framework cho phép phát triển mà không đòi hỏi cấu hình. Chỉ cần Grails và bạn đã sẵn sàng. Grails thực hiện tự động các "Tomcat webcontainer" và HSQLDB database trong suốt quá trình development. Nếu bạn triển khai ứng dụng Grails sau đó bạn có thể sử dụng webcontainer hoặc database khác.
Grails sử dụng GORM (Grails Object Relational Mapping) cho sự tồn tại của domain model. GORM là dựa trên Hibernate. Bạn có thể test với HSQLDB và run in production đối với database đơn giản khác bằng cách thay đổi tập tin cấu hình (DataSource.groovy).
Grails sử dụng JavaEE làm kiến trúc cơ bản và Spring để cấu trúc ứng dụng với dependency injection.
Grails là plug-in dựa vào và cung cấp sở hữu build system riêng (Gant). The Grails homepage cung cấp một vài pre-defined plugins để mở rộng Grails framework.
Trong thời gian bắt đầu một phát triển mới với Grails bạn chủ yếu sử dụng command line để tạo ra giao diện người dùng mới.
Grails là một framework dựa trên ngôn ngữ
Groovy .
Groovy is (almost) a superset of Java, e.g. most valid Java constructs cũng là valid Groovy constructs. Groovy có một số tính năng nâng cao được thêm vào các chức năng tiêu của Java, e.g. closures, hỗ trợ lists và maps, cú pháp ngắn hơn và nhiểu hơn nữa.
Groovy is (almost) a superset of Java, e.g. most valid Java constructs cũng là valid Groovy constructs. Groovy có một số tính năng nâng cao được thêm vào các chức năng tiêu của Java, e.g. closures, hỗ trợ lists và maps, cú pháp ngắn hơn và nhiểu hơn nữa.
Download Grails từ trang chủ Grails http://grails.codehaus.org/. Unzip download.
Setup your GRAILS_HOME environment variable trỏ đến thư mục cài đặt của Grails. Cũng thêm $GRAILS_HOME/bin đến the PATH variable.
Setup your GRAILS_HOME environment variable trỏ đến thư mục cài đặt của Grails. Cũng thêm $GRAILS_HOME/bin đến the PATH variable.
Tip
Chắc chắn rằng environment variable JAVA_HOME is set to the JDK and not the JRE. The JDK is required to develop with Grails.
Lets develop a guestbook for a website.
Lets create the application with the name
"de.vogella.grails.guestbook". Tạo một thư mục mà sẽ chứa Grails
application của bạn. Mở command shell, switch đến thư mục
bạn muốn lưu Grails Apps và gõ dòng lệnh sau.
Dòng lệnh này tạo cấu trúc thư mục và cấu hình đơn giản cho web application mới của bạn.
grails create-app de.vogella.grails.guestbook
Tip
Tên của ứng dụng được sử dụng cho URL trong khi ứng dụng chạy và war file sẽ được tạo sau đó.Dòng lệnh này tạo cấu trúc thư mục và cấu hình đơn giản cho web application mới của bạn.
Ứng dụng vừa mới tạo luôn sẵn sàng để chạy. Switch đến thư mục "de.vogella.grails.guestbook". Bạn có thể chạy ứng dụng với dòng lệnh sau.
Dòng lệnh này sẽ bắt đầu Grails internal web container và bạn sẽ nhận được tin nhắn "Server running. Browse to http://localhost:8080/de.vogella.grails.guestbook". Mở ngay trình duyệt web và paste URL này vào "http://localhost:8080/de.vogella.grails.guestbook"
Congratulations! Your first running Grails application.
grails run-app
Dòng lệnh này sẽ bắt đầu Grails internal web container và bạn sẽ nhận được tin nhắn "Server running. Browse to http://localhost:8080/de.vogella.grails.guestbook". Mở ngay trình duyệt web và paste URL này vào "http://localhost:8080/de.vogella.grails.guestbook"
Congratulations! Your first running Grails application.
Stop the server via "Ctrl + C". We need the command line to
create more elements.
Ứng dụng của chúng ta chưa có gì cả. Hãy bắt đầu bằng việc tạo domain
model.
For your feedback system we would like to have:
Grails có thể tạo ra các templates (empty classes và unit tests cho domain model của bạn). Tạo domain model thông qua các dòng lệnh sau:
Nõ sẽ tạo một groovy classes cho domain model cảu bạn trong đường dẫn ".\grails-app/domain". Trong đường dẫn ".\test\unit" bạn có thể thấy empty files cho unit tests của bạn.
Sử dụng một text editor để edit 3 classes như dưới đây:
Grails cho phép định nghĩa constraints ở domain model thông qua static method. Một số constraints, e.g. nullable là phản ánh trong database khác là chỉ sử dụng để xác thực giá trị thông qua giao diện người dùng, e.g. the url constraint.
-
Class Feedback: The feedback itself
-
Class User: The person who gives feedback
-
Class Comment: A remark(nhận xét) to the feedback
Grails có thể tạo ra các templates (empty classes và unit tests cho domain model của bạn). Tạo domain model thông qua các dòng lệnh sau:
grails create-domain-class de.vogella.grails.guestbook.Feedback
grails create-domain-class de.vogella.grails.guestbook.User
grails create-domain-class de.vogella.grails.guestbook.Comment
Nõ sẽ tạo một groovy classes cho domain model cảu bạn trong đường dẫn ".\grails-app/domain". Trong đường dẫn ".\test\unit" bạn có thể thấy empty files cho unit tests của bạn.
Sử dụng một text editor để edit 3 classes như dưới đây:
package de.vogella.grails.guestbook class Feedback { String title String feedback Date dateCreated // Predefined names by Grails will be filled automatically Date lastUpdated // Predefined names by Grails will be filled automatically // Relationsship to the other classes User user static hasMany=[comments:Comment] // Contrains are defined as static static constraints = { title(blank:false, nullable: false, size:3..80) feedback(blank:false, nullable:false,size:3..500) user(nullable:false) } }
package de.vogella.grails.guestbook class User { String name String email String webpage static constraints = { name (blank:false, nullable:false, size:3..30, matches:"[a-zA-Z1-9_]+") email (email:true) webpage (url:true) } String toString(){ return name; } }
package de.vogella.grails.guestbook class Comment { String comment Date dateCreated // Predefined names by Grails will be filled automatically Date lastUpdated // Predefined names by Grails will be filled automatically User user; // This will make sure that all comments for a feedback are deleted in case the feedback item is deleted static belongsTo=[feedback:Feedback] static constraints = { comment (blank:false, nullable: false, size:5..500) user (nullable: true) // Comments are allowed without a user } String toString(){ if (comment.size()>20){ return comment.substring(0,19); } else return comment; } }
Grails cho phép định nghĩa constraints ở domain model thông qua static method. Một số constraints, e.g. nullable là phản ánh trong database khác là chỉ sử dụng để xác thực giá trị thông qua giao diện người dùng, e.g. the url constraint.
Tip
All model class with have by default a version and id property of type Long and a toString() method. These methods will be dynamically injected if the model has not an own implementation. dataCreated and lastUpdated are also known by Grails and will be filled automatically.Tip
Changes in the domain model may require a restart of the Grails server and running the command "grails clean".
Grails support dynamic and static scaffolding for the user
interface. If you use dynamic scaffolding then a user interface for
the
domain class is dynamically generated by the Grails runtime. This
user
interface allows the operations Create, Read, Update and Delete
(CRUD).
To use dynamic scaffolding create controllers for your domain class via the following commands:
This will create controller classes in the directory "\grails-app\controllers".
Activate the dynamic scaffolding in each controller by replacing the line which starts with def index with "def scaffold = true ". For example for the FeedbackController.
Do this also for UserController and CommentController.Run the application again via:
Browse to http://localhost:8080/de.vogella.grails.guestbook". You should have a full CRUD (create, retrieve, update, delete) application available. To start the app, click on FeedbackController.
To use dynamic scaffolding create controllers for your domain class via the following commands:
grails generate-controller de.vogella.grails.guestbook.Feedback grails generate-controller de.vogella.grails.guestbook.User grails generate-controller de.vogella.grails.guestbook.Comment
This will create controller classes in the directory "\grails-app\controllers".
Activate the dynamic scaffolding in each controller by replacing the line which starts with def index with "def scaffold = true ". For example for the FeedbackController.
package de.vogella.grails.guestbook class FeedbackController { // Only change here def scaffold = true static allowedMethods = [save: "POST", update: "POST", delete: "POST"] def index = { redirect(action: "list", params: params) } def list = { params.max = Math.min(params.max ? params.int('max') : 10, 100) [feedbackInstanceList: Feedback.list(params), feedbackInstanceTotal: Feedback.count()] } def create = { def feedbackInstance = new Feedback() feedbackInstance.properties = params return [feedbackInstance: feedbackInstance] } def save = { def feedbackInstance = new Feedback(params) if (feedbackInstance.save(flush: true)) { flash.message = "${message(code: 'default.created.message', args: [message(code: 'feedback.label', default: 'Feedback'), feedbackInstance.id])}" redirect(action: "show", id: feedbackInstance.id) } else { render(view: "create", model: [feedbackInstance: feedbackInstance]) } } def show = { def feedbackInstance = Feedback.get(params.id) if (!feedbackInstance) { flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'feedback.label', default: 'Feedback'), params.id])}" redirect(action: "list") } else { [feedbackInstance: feedbackInstance] } } def edit = { def feedbackInstance = Feedback.get(params.id) if (!feedbackInstance) { flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'feedback.label', default: 'Feedback'), params.id])}" redirect(action: "list") } else { return [feedbackInstance: feedbackInstance] } } def update = { def feedbackInstance = Feedback.get(params.id) if (feedbackInstance) { if (params.version) { def version = params.version.toLong() if (feedbackInstance.version > version) { feedbackInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [message(code: 'feedback.label', default: 'Feedback')] as Object[], "Another user has updated this Feedback while you were editing") render(view: "edit", model: [feedbackInstance: feedbackInstance]) return } } feedbackInstance.properties = params if (!feedbackInstance.hasErrors() && feedbackInstance.save(flush: true)) { flash.message = "${message(code: 'default.updated.message', args: [message(code: 'feedback.label', default: 'Feedback'), feedbackInstance.id])}" redirect(action: "show", id: feedbackInstance.id) } else { render(view: "edit", model: [feedbackInstance: feedbackInstance]) } } else { flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'feedback.label', default: 'Feedback'), params.id])}" redirect(action: "list") } } def delete = { def feedbackInstance = Feedback.get(params.id) if (feedbackInstance) { try { feedbackInstance.delete(flush: true) flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'feedback.label', default: 'Feedback'), params.id])}" redirect(action: "list") } catch (org.springframework.dao.DataIntegrityViolationException e) { flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'feedback.label', default: 'Feedback'), params.id])}" redirect(action: "show", id: params.id) } } else { flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'feedback.label', default: 'Feedback'), params.id])}" redirect(action: "list") } } }
Do this also for UserController and CommentController.Run the application again via:
grails run-app
Browse to http://localhost:8080/de.vogella.grails.guestbook". You should have a full CRUD (create, retrieve, update, delete) application available. To start the app, click on FeedbackController.
Grails allows to simulate example data (this is called
bootstrapping).
To create example data you can use the class
BootStrap.groopy from
the
directory "./grails-app/conf" with some data.
This class is
automatically executed whenever the server is started
and can be used
to create some example data for testing.
Change the code to the following.
The grails server should pickup the change automatically. Wait a while (or re-start the server to be sure) and check if you get an error message.
Change the code to the following.
import de.vogella.grails.guestbook.* class BootStrap { def init = { servletContext -> User user = new User(name:'lars', email:'muster@muster.com', webpage:'http://www.vogella.com') User otherUser = new User(name:'jim', email:'jim@muster.com', webpage:'http://www.vogella.com') if (!user.save()){ log.error "Could not save user!!" log.error "${user.errors}" } if (!otherUser.save()){ log.error "Could not save otherUser!!" } Feedback feedback = new Feedback(title:'First feedback', feedback:'This is my first feedback', user:user) feedback.save() Comment comment = new Comment(comment:'Hello, my name is Jim', user:otherUser) comment.feedback = feedback comment.save(); } def destroy = { } }
The grails server should pickup the change automatically. Wait a while (or re-start the server to be sure) and check if you get an error message.
By default the data maintained in the web application are not
stored. If you entries should be saved to the database after server
shutdown use the following command to start it.
grails prod run-app
Tip
Remove the bootstrapped entries as you will otherwise get error as the system tries to create the same entries again.
To switch from dynamic scaffolding to static scaffolding you
need to have view. Grails can generated them for you.
Type in the following to create a scaffold for the controller and the view.
Remove the "def scaffold = true " in your controller to use your generated views.
This creates the GSP (Groovy Server pages) for your actions in the directroy "grails-app\views". GSP are standard HTML code with Groovy mixed in. Have a look at the coding. The controller defines several actions (list, show, delete,edit). For all these actions corresponding views have been created under grails-app/views.
Type in the following to create a scaffold for the controller and the view.
grails generate-views de.vogella.grails.guestbook.Feedback grails generate-views de.vogella.grails.guestbook.User grails generate-views de.vogella.grails.guestbook.Comment
Tip
If you receive the error "Error starting Sun's native2ascii" then make sure that your environment variable JAVA_HOME points to the JDK and not JRE. The JDK is required for this step.Remove the "def scaffold = true " in your controller to use your generated views.
This creates the GSP (Groovy Server pages) for your actions in the directroy "grails-app\views". GSP are standard HTML code with Groovy mixed in. Have a look at the coding. The controller defines several actions (list, show, delete,edit). For all these actions corresponding views have been created under grails-app/views.
If you not satisfied with the order of the fields you can
change the views directly. For example in the following view
I did change the order of the fields so that name is
displayed before comment.
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta name="layout" content="main" /> <title>Create Feedback</title> </head> <body> <div class="nav"> <span class="menuButton"><a class="home" href="${createLinkTo(dir:'')}">Home</a></span> <span class="menuButton"><g:link class="list" action="list">Feedback List</g:link></span> </div> <div class="body"> <h1>Create Feedback</h1> <g:if test="${flash.message}"> <div class="message">${flash.message}</div> </g:if> <g:hasErrors bean="${feedback}"> <div class="errors"> <g:renderErrors bean="${feedback}" as="list" /> </div> </g:hasErrors> <g:form action="save" method="post" > <div class="dialog"> <table> <tbody> <tr class="prop"> <td valign="top" class="name"> <label for="name">Name:</label> </td> <td valign="top" class="value ${hasErrors(bean:feedback,field:'name','errors')}"> <input type="text" id="name" name="name" value="${fieldValue(bean:feedback,field:'name')}"/> </td> </tr> <tr class="prop"> <td valign="top" class="name"> <label for="feedback">Feedback:</label> </td> <td valign="top" class="value ${hasErrors(bean:feedback,field:'feedback','errors')}"> <input type="text" id="feedback" name="feedback" value="${fieldValue(bean:feedback,field:'feedback')}"/> </td> </tr> </tbody> </table> </div> <div class="buttons"> <span class="button"><input class="save" type="submit" value="Create" /></span> </div> </g:form> </div> </body> </html>
Grails created the default CSS style sheets under the
directory web-app/css/main.css
You can directly change the main.css to make your application look different. For example if the feedback field should be larger then the name field add then following to main.css.
You can directly change the main.css to make your application look different. For example if the feedback field should be larger then the name field add then following to main.css.
#feedback { height: 80px; width: 160px; }
Type the following command to create a war archive. This archive
can be deployed to a web container, for example Tomcat.
grails war
The command "create-domain-class" create also automatically a
test for the domain-class. Go to your directory "test\integration"
and open the class "FeedbackTests.groovy".
You can run your test via the following command.
You can run your test via the following command.
grails test-app
The following requires that Eclipse with the Groovy plug-in is
installed. Please see
Groovy Eclipse Plugin
for more information.
After running "grails create-app" you may notice the .project and .classpath file. These Eclipse related files are created automatically and allow you to import the project into Eclipse. Import your project via File -> Import -> General -> "Existing Project into Workspace".
The environment variable "GRAILS_HOME" may not be set in Eclipse. Select your project, right-click on it and select properties. Select the Java Build Path and here the tab "Libraries. Press "Add Variable" and then "Configure Variables". Press New and add GRAILS_HOME.
After running "grails create-app" you may notice the .project and .classpath file. These Eclipse related files are created automatically and allow you to import the project into Eclipse. Import your project via File -> Import -> General -> "Existing Project into Workspace".
The environment variable "GRAILS_HOME" may not be set in Eclipse. Select your project, right-click on it and select properties. Select the Java Build Path and here the tab "Libraries. Press "Add Variable" and then "Configure Variables". Press New and add GRAILS_HOME.
Không có nhận xét nào:
Đăng nhận xét