- 浏览: 33919 次
最新评论
-
flyisland:
well done!我是搜索grails+ajax找到你的网站 ...
GORM翻译 -
stiffler:
谢谢!这篇文章解决了我的问题~支持,加油~期待更多精彩文章不知 ...
grails的命名策略和数据库连接
看到Grails的validation标签居然是没实现,一下子大受打击!很郁闷,但是没办法,偶们还是自己来实现一下这个重要的功能把.
Grails的tag其实一般都在\grails-app\taglib下面,可以自行修改源程序来修改tag的表现.validation标签就在ValidationTagLib.groovy这个文件里面.只要修改一下代码就可以了,由于实现过程比较繁杂,直接贴出源代码,需要注意的是:
第一个地方:” import org.geszjava.grails.utils.ChineseProperty as CP;”这条语句,偶是自己写一个类来进行属性名和表单说明的转换,这一步算是偷懒了.有好处也有坏处,好处是不用写那么多Local信息了,直接拿default的来就可以了.坏处是Locale的处理上有问题.当然我现在的项目只支持中文.:),以后有时间可以考虑本地化问题.BTW:grails自己的本地化支持目前好像还没有?不太清楚.呵呵.
第二个地方:”size”这种Type用的是”minLength,maxLength”,而不是原先的intRange,具体怎么回事用脑袋想想也知道:两者在javascript上的实现天差地远.
第三个地方:splitType(),由于有了”minLength,maxLength”这种类型,那么整合的时候当然不能直接写成validationMinLength,maxLength()这样的东东,可以说是个比较严重的错误,所以这里顺便更改了一下
第四个地方: 看看这段代码
Grails的tag其实一般都在\grails-app\taglib下面,可以自行修改源程序来修改tag的表现.validation标签就在ValidationTagLib.groovy这个文件里面.只要修改一下代码就可以了,由于实现过程比较繁杂,直接贴出源代码,需要注意的是:
第一个地方:” import org.geszjava.grails.utils.ChineseProperty as CP;”这条语句,偶是自己写一个类来进行属性名和表单说明的转换,这一步算是偷懒了.有好处也有坏处,好处是不用写那么多Local信息了,直接拿default的来就可以了.坏处是Locale的处理上有问题.当然我现在的项目只支持中文.:),以后有时间可以考虑本地化问题.BTW:grails自己的本地化支持目前好像还没有?不太清楚.呵呵.
第二个地方:”size”这种Type用的是”minLength,maxLength”,而不是原先的intRange,具体怎么回事用脑袋想想也知道:两者在javascript上的实现天差地远.
第三个地方:splitType(),由于有了”minLength,maxLength”这种类型,那么整合的时候当然不能直接写成validationMinLength,maxLength()这样的东东,可以说是个比较严重的错误,所以这里顺便更改了一下
第四个地方: 看看这段代码
switch(vt) { case 'mask': out << "function ${form}_mask() {"; break; case 'intRange': out << "function ${form}_intRange() {"; break; case 'floatRange': out << "function ${form}_floatRange() {"; break; case 'maxLength': out << "function ${form}_maxlength() {"; break; case 'minLength': out << "function ${form}_minlength() {"; break; case 'email': out << "function ${form}_email() {"; break; case 'creditCard': out << "function ${form}_creditCard() {"; break; case 'required': out << "function ${form}_required() {"; break; default: out << "function ${form}_${vt}() {"; break; } 原先的代码太粗略,minlength和maxlength不能工作,所以写个比较麻烦的代码,其实修改一下那个MAP就可以了,不过那样修改的东西太多了,不合算./* Copyright 2004-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT c;pWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.text.MessageFormat import org.springframework.validation.Errors; import org.springframework.context.NoSuchMessageException; import org.springframework.web.servlet.support.RequestContextUtils as RCU; import org.codehaus.groovy.grails.commons.GrailsClassUtils as GCU; import org.geszjava.grails.utils.ChineseProperty as CP; /** * A tag lib that provides tags to handle validation and errors * * @author Graeme Rocher * @since 17-Jan-2006 */ class ValidationTagLib { /** * Checks if the request has errors either for a field or global errors */ def hasErrors = { attrs, body -> def model = attrs['model'] def checkList = [] if(model) { checkList = model.findAll { k,v -> grailsApplication.isGrailsDomainClass(v.class) } } if(attrs['bean']) { checkList << attrs['bean'] } else { if(request.attributeNames) { request.attributeNames.each { ra -> if(ra) { if(ra instanceof Errors) checkList << ra else if(grailsApplication.isGrailsDomainClass(ra.class)) checkList << ra } } } } for(i in checkList) { def errors = null if(grailsApplication.isGrailsDomainClass(i.class)) { if(i.hasErrors()) errors = i.errors } else if(i instanceof Errors) { errors = i } if(errors) { if(attrs['field']) { if(errors.hasFieldErrors(attrs['field'])) { body() } } else { body() } } } } /** * Loops through each error for either field or global errors */ def eachError = { attrs, body -> def model = attrs['model'] def errorList = [] if(model) { errorList = model.findAll { k,v -> grailsApplication.isGrailsDomainClass(v.class) } } if(attrs['bean']) { errorList << attrs['bean'] } else { request.attributeNames.each { def ra = request[it] if(ra) { if(ra instanceof Errors) errorList << ra else if(grailsApplication.isGrailsDomainClass(ra.class)) errorList << ra } } } for(i in errorList) { def errors = null if(grailsApplication.isGrailsDomainClass(i.class)) { if(i.hasErrors()) errors = i.errors } else if(i instanceof Errors) { errors = i } if(errors && errors.hasErrors()) { if(attrs['field']) { if(errors.hasFieldErrors(attrs['field'])) { errors.getFieldErrors( attrs["field"] ).each { body(it) } } } else { errors.allErrors.each { body( it ) } } } } } /** * Loops through each error and renders it using one of the supported mechanisms (defaults to "list" if unsupported) */ def renderErrors = { attrs, body -> def renderAs = attrs.remove('as') if(!renderAs) renderAs = 'list' if(renderAs == 'list') { out << "<ul>" eachError(attrs, { out << "<li>" message(error:it) out << "</li>" } ) out << "</ul>" } } /** * Resolves a message code for a given error or code from the resource bundle */ def message = { attrs -> def messageSource = grailsAttributes .getApplicationContext() .getBean("messageSource") def locale = RCU.getLocale(request) if(attrs['error']) { def error = attrs['error'] def defaultMessage = ( attrs['default'] ? attrs['default'] : error.defaultMessage ) def message = messageSource.getMessage( error.code, error.arguments, defaultMessage, locale ) if(message) { out << message } else { out << error.code } } if(attrs['code']) { def code = attrs['code'] def defaultMessage = ( attrs['default'] ? attrs['default'] : code ) def message = messageSource.getMessage( code, null, defaultMessage, locale ) if(message) { out << message } else { out << code } } } // Maps out how Grails contraints map to Apache commons validators static CONSTRAINT_TYPE_MAP = [ email : 'email', creditCard : 'creditCard', match : 'mask', blank: 'required', nullable: 'required', maxSize: 'maxLength', minSize: 'minLength', range: 'intRange', size: 'maxLength,minLength', length: 'maxLength,minLength' ] /** * Validates a form using Apache commons validator javascript against constraints defined in a Grails * domain class * * TODO: This tag is a work in progress 修改 */ def validate = { attrs, body -> def form = attrs["form"] def againstClass = attrs["against"] if(!form) throwTagError("Tag [validate] is missing required attribute [form]") if(!againstClass) { againstClass = form.substring(0,1).toUpperCase() + form.substring(1) } def app = grailsAttributes.getGrailsApplication() def dc = app.getGrailsDomainClass(againstClass) if(!dc) throwTagError("Tag [validate] could not find a domain class to validate against for name [${againstClass}]") def constrainedProperties = dc.constrainedProperties.collect { k,v -> return v } def appliedConstraints = [] constrainedProperties.each { appliedConstraints += it.collect{ it.appliedConstraints } } appliedConstraints = appliedConstraints.flatten() def fieldValidations = [:] appliedConstraints.each { def validateType = CONSTRAINT_TYPE_MAP[it.name] if(validateType) { if(fieldValidations[validateType]) { fieldValidations[validateType] << it } else { fieldValidations[validateType] = [it] } } } out << '<script type="text/javascript">\n' def scriptNameUtil = "org/apache/commons/validator/javascript/validateUtilities.js" def inStreamUtil = getClass().classLoader.getResourceAsStream(scriptNameUtil) if(inStreamUtil) { out << inStreamUtil.text } fieldValidations.each { k,v -> def validateType = k if(validateType) { def validateTypes = [validateType] if(validateType.contains(",")) { validateTypes = validateType.split(",") } validateTypes.each { vt -> // import required script def scriptName = "org/apache/commons/validator/javascript/validate" + vt.substring(0,1).toUpperCase() + vt.substring(1) + ".js" def inStream = getClass().classLoader.getResourceAsStream(scriptName) if(inStream) { out << inStream.text } switch(vt) { case 'mask': out << "function ${form}_mask() {"; break; case 'intRange': out << "function ${form}_intRange() {"; break; case 'floatRange': out << "function ${form}_floatRange() {"; break; case 'maxLength': out << "function ${form}_maxlength() {"; break; case 'minLength': out << "function ${form}_minlength() {"; break; case 'email': out << "function ${form}_email() {"; break; case 'creditCard': out << "function ${form}_creditCard() {"; break; case 'required': out << "function ${form}_required() {"; break; default: out << "function ${form}_${vt}() {"; break; } //out << "function ${form}_${vt.toLowerCase()}() {" v.each { constraint -> out << "this.${constraint.propertyName} = new Array(" out << "'${constraint.propertyName}'," // the field //out << '"Test message"' // TODO: Resolve the actual message def clazzName = againstClass?.toLowerCase() out << getMessage(vt, clazzName, constraint.propertyName, constraint) switch(vt) { case 'mask': out << ",function() { return '${constraint.regex}'; }";break; case 'intRange': out << ",function() { if(arguments[0]=='min') return ${constraint.range.from}; else return ${constraint.range.to} }";break; case 'floatRange': out << ",function() { if(arguments[0]=='min') return ${constraint.range.from}; else return ${constraint.range.to} }";break; case 'maxLength': if (!isSizeConstraint(constraint)) { out << ",function() {return ${constraint.maxSize};}"; } else { out << ",function() {return ${constraint.range.to};}"; } break; case 'minLength': if (!isSizeConstraint(constraint)) { out << ",function() {return ${constraint.minSize};}"; } else { out << ",function() {return ${constraint.range.from};}"; } break; } out << ');\n' } out << "}\n" } } } out << 'function validateForm(form) {\n' fieldValidations.each { k,v -> def splittedTypes = splitType(k); for (spt in splittedTypes) { def validateType = spt.substring(0,1).toUpperCase() + spt.substring(1) out << "if(!validate${validateType}(form)) return false;\n" } } out << 'return true;\n'; out << '}\n' out << "document.forms['${attrs['form']}'].onsubmit = function() {return validateForm(this);}\n" out << '</script>' } //添加 def static messageMap = [ "mask" : "{0}不符合正则表达式[{1}]", "creditCard" : "{0}不是一个合法的信用卡号", "email" : "{0}不是一个合法的Email地址", "intRange" : "{0}不在{1}到{2}之内", "floatRange" : "{0}不在{1}到{2}之内", "maxLength" : "{0}的长度大于{1}", "minLength" : "{0}的长度小于{1}", "required" : "{0}不能为空", ] //添加 def static splitType(type) { if (type.indexOf(",") >= 0) { StringTokenizer st = new StringTokenizer(type, ","); def retList = [] while (st.hasMoreTokens()) { retList << st.nextToken(); } return retList; } else { return [type]; } } def static isSizeConstraint(constraint) { if (constraint.getClass().getName() == "org.codehaus.groovy.grails.validation.ConstrainedProperty\$SizeConstraint") return true else return false } //添加 def getMessage(vt, clazzName, propertyName, constraint) { def cn = CP.getChinesePropertyName(clazzName + "." + propertyName) if (!cn) cn = propertyName Object[] args = new Object[3] args[0] = cn def omsg = messageMap[vt] if (!omsg) omsg = "存在未知错误" def msg = ""; switch(vt) { case 'email': break case 'creditCard': break case 'mask': args[1] = constraint.regex break case 'intRange': args[1] = constraint.range.from args[2] = constraint.range.to break case 'floatRange': args[1] = constraint.range.from args[2] = constraint.range.to break; case 'maxLength': if (!isSizeConstraint(constraint)) { args[1] = constraint.maxSize } else { args[1] = constraint.range.to } break case 'minLength': if (!isSizeConstraint(constraint)) { args[1] = constraint.minSize } else { args[1] = constraint.range.from } break } return "\"" + MessageFormat.format(omsg, args) + "\"" } }
发表评论
-
grails0.22压力测试
2006-11-11 16:58 1800grails0.3终于发布了,不过好像改了很多东西,正在看文档 ... -
grails的命名策略和数据库连接
2006-08-29 07:31 3470grails直接使用hibernate的ImprovedNam ... -
给grails添加text映射支持
2006-08-27 01:45 2627在grails中,domain class的String字段总 ... -
GORM翻译
2006-08-17 14:31 4102第一次翻译,翻译的不好,希望大牛们可以校正,说实话grails ... -
在grails job中碰到的问题的解决
2006-08-15 15:26 2438想在job中直接调用velocity,于是把velocity- ... -
Grails的Ajax
2006-08-15 15:12 4353grails支持ajax,目前可以使用三种库: prototy ... -
grails的mvc相关功能
2006-08-02 16:45 2722grails的Domain Class/*.gsp(或 ... -
grails的job
2006-08-02 16:44 3532打算再我的项目中引入静态页面的生成,因为这几天看代码看的太紧张 ... -
Grails0.2的一个Bug[输出的html文件内容缺失]修理过程
2006-08-02 16:42 2172[Blog搬家到Javaeye] 一听 ...
相关推荐
Domain Classes使用Groovy的元编程特性,如属性验证和动态方法,提供数据验证和业务逻辑。 2. **视图(View)**: 视图负责展示数据,通常使用GSP(Grails Server Pages)技术,这是一种结合了HTML和Groovy的模板...
描述中的"javascript and ajax using in grails"强调了JavaScript在Grails应用中的重要性。JavaScript是实现Ajax交互的主要语言,通常用于处理用户交互和动态更新页面。Grails提供了与jQuery等流行JavaScript库集成...
《Grails权威指南》是一本全面深入探讨Grails框架的专著,旨在帮助读者掌握这一强大的Web开发工具。Grails是一种基于Groovy语言的开源框架,它为构建现代、高效的应用程序提供了简洁高效的解决方案。本指南针对不同...
验证是Web开发中不可或缺的一部分,Grails通过声明约束和验证约束来实现。它支持客户端验证,使得可以在用户提交表单之前校验数据。Grails的国际化支持非常好,开发者可以通过简单的配置来为不同的语言环境定制应用...
【Grails项目搭建详解】 Grails是一个基于Groovy语言的开源Web应用框架,它简化了开发过程,尤其适合快速构建动态网站。在Eclipse中搭建Grails项目可能相对复杂,但通过以下步骤,即使是初学者也能顺利进行。 1. *...
在开发Web应用时,将Grails(一个基于Groovy语言的开源全栈式Web应用框架)与JQuery(一个轻量级、高性能的JavaScript库)集成可以极大地提升用户体验和开发效率。下面我们将深入探讨如何在Grails项目中整合JQuery,...
### Grails入门指南知识点 #### 一、Grails框架简介 - **背景**: Grails是一个基于Groovy语言的开源Web应用框架,适用于Java平台。它旨在简化开发过程,提高开发效率,尤其受到那些希望保留Java环境同时寻求更高效...
《Grails用户手册》 Grails,作为一个基于Groovy语言的开源Web应用框架,深受开发者喜爱,它简化了Java开发的复杂性,提供了强大的MVC(Model-View-Controller)架构,以及丰富的插件系统。这份用户手册将帮助你...
验证Grails是否安装成功的方法是在命令行中输入`grails`,如果出现Grails的欢迎信息,则表示安装成功。 **3. 安装Groovy** 最后一步是安装Groovy语言。本文档中的版本为1.5.4,可以从以下地址下载: - 下载地址:...
**Grails 概述** Grails 是一个基于 Groovy 语言的开源 web 应用程序框架,它构建在 Java 平台上,旨在提高开发效率,简化常见 Web 开发任务。Grails 遵循 Model-View-Controller (MVC) 架构模式,允许开发者快速...
- **Filters**:在请求处理前或后执行的逻辑,可用于登录验证、日志记录等。 4. **GORM(Grails Object Relational Mapping)** GORM 提供了对数据库的操作接口,使得开发者可以通过面向对象的方式操作数据,减少...
对于Grails开发,我们需要的是Eclipse中的Grails插件,它能够提供对Grails项目的创建、运行、调试等一系列功能。 **Grails**是基于Groovy语言的全栈式Web开发框架,它借鉴了Ruby on Rails的设计理念,提供了快速...
总的来说,"第一个grails程序"是一个基础的登录验证系统,展示了Grails如何快速构建Web应用,包括处理用户请求、与数据库交互、实现业务逻辑和视图渲染。这个简单的例子对于初学者来说,是理解Grails框架工作原理和...
**Grails登录系统详解** Grails是一个基于Java的开源Web应用程序框架,它使用Groovy语言进行开发,提供了高效、简洁的编程模型。在Grails中实现用户登录功能是构建任何Web应用的基础,它确保了数据的安全性和用户...
### Grails 快速开发 Web 应用程序 #### 一、Grails 概述 Grails 是一种基于 Groovy 的开源应用框架,用于简化 Web 应用程序的开发过程。它采用约定优于配置的原则,这使得开发者可以更快地创建功能丰富的 Web ...
通过在命令行输入`grails help`验证安装是否成功。 创建Grails应用使用`grails create-app`命令,例如创建名为"Contact"的应用。Grails会自动生成包含默认目录结构的应用程序。目录结构包括`grails-app/conf`存储...