事先说明,我对Ruby只懂个皮毛。而Rails则没有接触过。看了视频后,还是能看懂的,语法什么的大概都能猜到意思。现在学习Grails,所以想用Grails来实现看看。
先分析下,视频里面所讲的Blog的内容。以Grails的名词来解释。(不知道Rails里面的专业术语。。。。)
1.首先是两个领域模型,Post和Comment。是一对多的关系。Post里面有title和body属性,不能为空。Comment里面持有Post的id以及body属性。
2.身份的验证。发布,编辑Post需要身份验证。
3.实现RSS浏览Post
4.回复Comment
5.AJAX实现动态显示添加的Comment
下面就开始使用Grails来实现这个Blog。开发工具是Intellij Idea + Grails插件。
首先,创建Blog项目,和创建Java项目是类似的。如果你爱用命令行那就敲命令吧。
创建完了项目,那么就开始着手实现了,当然是先创建两个领域模型Post和Comment.
class Post {
static hasMany = [comment:Comment]
String title
String body
}
class Comment {
Post post
String body
}
如果使用过任何ORM框架,那么这段代码没有难理解的地方吧!
静态的hasMany设置是个Groovy的hashmap:键是comment;值是Comment类.
接着创建Post和Comment的CRUD.
新建两个Controller,GroovyController和CommentController。如下所示。
class PostController {
def scaffold = Post
}
class CommentController {
def scaffold = Comment
}
def scaffold = ***的意思就是创建最基本的CRUD。这样你就可以运行项目了。看看效果。
框框内就是两个Controller。首先看看PostController。在你点击了NewPost之后,你会立刻发现两个问题。Body在Title的上方,Body的输入区域是textfield,而一般应该是textarea。先不管这个,随便输入点信息进去,是没有问题的。说明目前基本流程对了,那么下面开始修改刚才说的问题,并给Title和Body加上不能为空的限制。其实排序和限制可以说是一样的东西。往下看。
打开Post领域模型。修改代码如下
class Post {
static hasMany = [comment:Comment]
String title
String body
static constraints = {
title(maxLength:50,blank:false)
body(blank:false)
}
}
这个闭包应该很好理解吧?title长度不能超过50,不能为空,body也不能为空。而排序也已经被完成了。Grails会按照限制里面的顺序来列出内容。但是这里需要重新启动服务。否则不会出先效果。重启服务器试试看吧。
顺个便给Comment也加个限制。
class Comment {
Post post
String body
static constraints = {
post()
body(blank:false)
}
}
这里对post没有限制,但是如果你想要post在body前面,那么需要这么写。
接着修改页面显示。你需要general-all controller。我没有在Intellij Idea里面找到哪里可以做此操作(希望知道的告知一声,谢谢。)手动删除PostController和CommentController.使用命令行到项目的根路径下面。输入grails generate-all。在出现提示:Domain Class name not specified. Please enter:时,输入Post。结束以后再次输入grails generate-all,接着输入Comment。这样就可以了。
现在你会发现两个Controller里面多了很多代码,不管这些。到views目录下面,找到post目录,里面会有四个gsp文件(类似jsp的东西,学过jsp,看gsp没障碍)。刚才出问题的是add.gsp。进入此页面。找到body,将input标签替换为textarea标签即可,这里有个问题,<textarea></textarea>需要这样写,否则会有问题。至少我这里是。
接着就是身份验证了。
视频里面是使用了一个filter来过滤的(看着是挺简单的)。也没写页面什么,迷惑。
在Grails里面我是这么实现的!添加一个新的领域模型User来控制访问权限,登录后存放到session里面,然后编辑或创建的时候检查session。没有则转到登录页面。
这里也和视频里面一样就不查数据库了,检验用户名和密码是否都为admin,是就登录,否则就还在登录页面。
先建立User领域模型。然后generall-all。
class User {
String userId
String password
static constraints = {
userId(blank:false)
password(minLength:6,blank:false)
}
}
接着手动的创建登录页面和添加action。
这里的动作比较大一点。在UserController里面添加如下代码
def login = {
if (request.method == "GET") {
session.userId = null
def userInstance = new User()
}
else {
if(params.userId == "admin" && params.password == "admin"){
def userInstance = new User(userId:params.userId,password:params.password)
session.userId = userInstance.userId
redirect(controller: 'post')
}else {
flash['message'] =
'Please enter a valid user ID and password'
}
}
}
如果登录成功则跳转到post控制器,否则打印错误信息。
再在views目录下的user里面添加一个login.gsp,添加如下代码。
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8"/>
<meta name="layout" content="main" />
<title>Log in</title>
</head>
<body>
<div class="body">
<h1>Please log in</h1>
<g:if test="${flash.message}">
<div class="message">${flash.message}</div>
</g:if>
<g:hasErrors bean="${race}">
<div class="errors">
<g:renderErrors bean="${user}" as="list" />
</div>
</g:hasErrors>
<g:form controller="user" method="post" >
<div class="dialog">
<table>
<tr class='prop'>
<td valign='top' class='name'>
<label for='userId'>User ID:</label>
</td>
<td valign='top' class='value '>
<input type="text" maxlength='8'
name='userId'
value='${user?.userId}'/>
</td>
</tr>
<tr class='prop'>
<td valign='top' class='name'>
<label for='password'>
Password:
</label>
</td>
<td valign='top' class='value '>
<input type="password" maxlength='8'
name='password'
value='${user?.password}'/>
</td>
</tr>
</table>
</div>
<div class="buttons">
<span class="button">
<g:actionSubmit value="Log in" />
</span>
</div>
</g:form>
</div>
</body>
</html>
现在登录就做好了,怎样把他给添加到流程里面去。这里需要一个Filter,在conf文件夹里面创建一个LoginFilters的groovy类,一定要以Filters结尾。
添加如下代码:
class LoginFilters {
def filters = {
loginCheck(controller: 'post', action: '*') {
before = {
if (!session.userId) {
if (actionName.equals('create')||actionName.equals('delete')||actionName.equals('update')||actionName.equals('edit')) {
redirect(controller: 'user', action: 'login')
return false
}
}
}
}
}
}
作用就是,当post里面调用的是create,delete,edit或者update Action的时候,如果没有登录则跳转到登录页面。
这样,权限就设置好了。再进行一下改进,因为这里只要登录成功后就会跳转到list页面,这肯定有问题,应该先记录用户要登录的页面,在登录成功后,再跳转到那个页面。
修改LoginFilters,如下
class LoginFilters {
def filters = {
loginCheck(controller: 'post', action: '*') {
before = {
if (!session.userId) {
if (actionName.equals('create')||actionName.equals('delete')||actionName.equals('update')||actionName.equals('edit')) {
def originalRequestParams =[controller:controllerName,action:actionName]
originalRequestParams.putAll(params)
session.originalRequestParams = originalRequestParams
redirect(controller: 'user', action: 'login')
return false
}
}
}
}
}
}
再修改下,UserController里面的login Action,如下
def login = {
if (request.method == "GET") {
session.userId = null
def userInstance = new User()
}
else {
if(params.userId == "admin" && params.password == "admin"){
def userInstance = new User(userId:params.userId,password:params.password)
session.userId = userInstance.userId
def redirectParams =session.originalRequestParams ?session.originalRequestParams :[controller:'post']
redirect(redirectParams)
}else {
flash['message'] =
'Please enter a valid user ID and password'
}
}
}
这样身份验证就完全添加好了。
接着是RSS功能.
Grails并没有对RSS或者Atom提供直接支持。你可以通过控制器render方法的XML能力来构造RSS或者ATOM。尽管如此,还是有一个Feeds 插件 (基于流行的 ROME 开发库)来为Grails提供RSS和Atom的生成器 (Grails参考手册13.3 )
插件可以到http://plugins.grails.org/下载。
或者使用命令行,到项目根路径下键入grails install-plugin feeds
然后在,PostController里添加一个Action
def feed = {
render(feedType:"rss", feedVersion:"2.0") {
title = "My test feed"
link = "http://localhost:8080/Blog/post/feed"
description = "The funky Grails news feed"
Post.list().each() { post ->
entry(post.title) {
link = "http://localhost:8080/Blog/post/show/${post.id}"
post.body // return the content
}
}
}
}
然后开始添加Comment,你在保存完Post后,应该发现了,Post的show页面里面就有一个Comment的字段来显示Comment。而Comment本来就有add方法,所以只需要两个整合一下就可以了,将Comment的create.gsp页面的form内容copy到Post的show.gsp页面里面去。在g:form标签里面添加一个属性
controller="comment"
因为这个页面现在有两个form,而此页面默认的controller是PostController,所以修改此controller为Comment。然后修改一下CommentController里的save Action,重定向修改为
redirect(controller:'post',action:'show',id:commentInstance.post.id)
即保存后还跳转到此post的show.gsp页面。页面结构就先不管了,功能是实现了。很简单吧!(我摸索了差不多1天时间
)
最后就是添加AJAX了。
Grails默认装载Prototype 库,但是通过Plug-in 系统提供像Dojo , Yahoo UI 和 Google Web Toolkit 等其他框架的支持.(Grails中文参考手册).
这里就使用默认支持的Prototype。在Post的show.gsp页面的head标签里面添加,Prototype支持。
<g:javascript library="prototype" />
最后就是AJAX实现,就是使用一个标签和render就可以了。将页面里面提交comment的按钮修改为AJAX按钮。同时将g:form里面的属性都去掉就可以了。
<div class="buttons">
<g:submitToRemote controller="comment" action="save" update="[success:'comments',failure:'error']" value="CreateComment"/>
</div>
这里的update就是动态刷新用的,成功就刷新id为comments的标签,否则就是id为error的标签。
修改下save Action.将rediect修改为render。这里应该是我对Grails不熟悉的原因。由于在gsp里面列Comment的标签是g:each,我不知道是否可以动态的改变它,我没找到办法,或者就是不可以。我直接在ul上加的comments id。然后在save Action里面组装了一下得到的Comments,返回一个str.
def save = {
def commentInstance = new Comment(params)
if(!commentInstance.hasErrors() && commentInstance.save()) {
flash.message = "Comment ${commentInstance.id} created"
def comments = Comment.findAllByPost(commentInstance.post)
def str = ""
comments.each {str = str + "<li>" + it + "</li>"}
render(str)
// redirect(controller:'post',action:'show',id:commentInstance.post.id)
}
else {
render(view:'create',model:[commentInstance:commentInstance])
}
}
这样,整个Blog就搞定了。页面上差异肯定是比较大一点,修改就行了。功能和ruby的基本相同了。有一点不同的应该是RSS那里,ruby会在浏览器的地址栏出现一个rss标签,而这里只能输入地址,应该也是可以的,我刚接触而已,做个实验罢了。如果熟悉Grails,相信15分钟之内是能搞定这个的!
ps:附件不知道会不会乱码,linux下打的包。。。。
- 大小: 46.2 KB
分享到:
相关推荐
Groovy 和 Grails 与 Ruby on Rails 一样,都追求开发效率和简洁性,但它们建立在不同的语言基础之上。Ruby on Rails 是基于 Ruby 语言,而 Grails 则是基于 Groovy。虽然 Grails 受到 Rails 的启发,但它采用了 ...
Grails则是一个构建于Groovy之上的开源Web应用框架,它借鉴了Ruby on Rails的设计模式,提供了快速开发的能力,强调代码的简洁性和可读性。 在“Groovy轻松入门—Grails实战基础篇”中,我们将探讨以下几个关键知识...
Grails,则是基于Groovy构建的一个现代Web应用框架,它借鉴了Ruby on Rails的设计理念,致力于提供快速开发的解决方案。Grails的主要优点包括MVC(模型-视图-控制器)架构、GORM(Grails Object Relational Mapping...
- **实战技巧**:包括 GORM (Groovy Object Relational Mapping) 的使用、如何在 Grails 中实现 Ajax 功能、处理遗留数据库的方法、利用遗留框架以及如何在 Grails 中使用 WebFlow。 - **高效编程系列**:涵盖使用 ...
Grails则是一个基于Groovy的开源Web应用框架,它借鉴了Ruby on Rails的设计理念,提供了模型-视图-控制器(MVC)架构模式,简化了开发流程,使开发者能快速创建全功能的Web应用。Grails的特性包括自动化 ORM(对象...
Grails 的设计深受Ruby on Rails的影响,提供了MVC(模型-视图-控制器)架构模式,允许开发者快速构建动态、数据库驱动的Web应用。 **Groovy 语言基础** Groovy 是一种动态类型的、面向对象的编程语言,它可以无缝...
Grails是一个现代的MVC Web框架,它受到Ruby on Rails的启发,建立在稳固的砖石和最佳组件之上。Grails的开发旨在提高Web应用开发的生产效率,并使得使用强大且动态的Groovy语言进行编程变得更加有趣。Grails框架...
**Grails**是基于Groovy语言的全栈式Web开发框架,它借鉴了Ruby on Rails的设计理念,提供了快速开发的可能。Grails的核心特性包括MVC架构、领域驱动设计(GORM)、自动化构建过程以及丰富的插件系统。通过Eclipse的...
"Groovy need not rails"指的是Groovy并不需要像Ruby on Rails那样的全栈框架,因为Groovy自身就提供了强大的工具和库来构建Web应用程序。Webx是一个基于Groovy的框架,它旨在简化Web应用开发,提供类似于Rails的...
Grails 借鉴了Ruby on Rails的设计理念,引入了GORM(Grails Object Relational Mapping)用于数据库操作,以及一系列的插件系统,支持快速构建复杂的Web应用程序。 2. **Groovy语言基础** Grails 采用Groovy作为...
它借鉴了Ruby on Rails的许多优秀理念,同时提供了Java平台的强大功能和兼容性。在本文中,我们将深入探讨Grails的安装、应用程序创建、核心概念以及其在敏捷开发中的应用。 ### 1. 安装Grails 安装Grails通常涉及...
Grails是一个基于Groovy语言的全栈式Web开发框架,它吸收了Ruby on Rails的设计理念,提供了简洁的语法和强大的功能。 描述中提到“freemarker是一个比较好用的java模板引擎,grails也对它有很好的支持”。这暗示在...
Grails是一个基于Groovy语言的开源Web应用框架,它借鉴了Ruby on Rails的许多优秀理念,旨在提高开发效率和代码可读性。 文档主要涵盖以下几个核心知识点: 1. **环境配置**:首先,开发者需要了解如何安装和配置...
Grails是一款基于Groovy语言的、高效的Web应用开发框架,它借鉴了Ruby on Rails的许多优秀特性。MongoDB则是一种流行的NoSQL数据库,以其灵活性、高性能和易于扩展性而闻名。 首先,我们需要确保已正确安装了Grails...
JRuby则可以使用Ruby的大量库,如Rails框架,以及各种测试和自动化工具。 在高级特性上,Groovy的AST(抽象语法树)转换允许在编译时自定义语言行为,而JRuby则利用Ruby的元编程能力提供类似的功能。 最后,演示...