`
sillycat
  • 浏览: 2552929 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Grails(7)Guide Book Chapter 8 The Web Layer Controller

 
阅读更多
Grails(7)Guide Book Chapter 8 The Web Layer Controller
7.1.4 Redirects and Chaining
Redirects
Actions can be redirected using redirect controller method:
class OverviewController {
     def login() {}
     def find(){
          if(!session.user){
               redirect(action: 'login')
               return
          }
          ...
     }
}

Call the action in the same controller class:
redirect(action: login)

Redirect to another controller
redirect(controller: 'home', action: 'index')

A URI for a resource relative the application context path:
redirect(uri: "/login.html")

Or redirect to a full URL:
redirect(url: "http://grails.org")

Parameters can optionally be passed from one action to the next using the params argument of the method:
redirect(action: 'myaction', params: [myparam: "myvalue"]

Since the params object is a Map, we can use it to pass the current request parameters from one action to the next:
redirect(action: "next", params: params)

Fragment
redirect(controller: "test", action: "show", fragment: "profile")

Chaining

7.1.5 Controller Interceptors
Before Interception
The beforeInterceptor intercepts processing before the action is executed. If it returns false, then the intercepted action will not be executed.
def beforeInterceptor = {
     println "Tracing action ${actionUri}"
}

The above is declared inside the body of the controller definition.

def beforeInterceptor = [action: this.&auth, exempt: 'login']

private auth(){
     if(!session.user){
          redirect(action: 'login')
          return false   // the original action will not execute
     }
}

def login(){}

The above code defines a method called auth. A private method is used so that it is not exposed as an action to the outside world. The beforeInterceptor then defines an interceptor that is used on all actions except the login action.

After Interception
def afterInterceptor = { model ->
     println "Tracing action ${actionUri}"
}

The after interceptor takes the resulting model as an argument and can hence manipulate the model or response.

def afterInterceptor = { model, modelAndView ->
     println "Current view is ${modelAndview.viewname}"
     if(model.someVar) modelAndView.viewName = "/mycontroller/someotherview"
     println "View is now ${modelAndView.viewName}"
}

Interception Conditions
def beforeInterceptor = [action: this.&auth, except: ['login', 'register']]

except if for exception for our interceptors for all the other actions.

only is the only condition for the only action we intercept.
def beforeInterceptor = [action: this.&auth, only: ['secure']]

7.1.6 Data Binding
Binding Request Data to the Model
def save(){
     def b = new Book(params)
     b.save()
}

That is magic, the data binding happens within the code new Book(params). By passing the params object to the domain class constructor Grails automatically recognizes that you are trying to bind from request parameters.

We can also use properties to bind the parameters to existing instance:
def save(){
     def b = Book.get(params.id)
     b.properties = params
     b.save()
}

Data binding and Single-ended Associations
…snip…

Data binding with Multiple domain classes
/book/save?book.title=booktitle&author.name=Carl

def b = new Book(params.book)
def a = new Author(params.author)

Data Binding and Action Arguments
class AccountingController {
     //accountNumber will be initialized with the value of params.accountNumber
     //accountType will be initialized with params.accountType
     def displayInvoice(String accountNumber, int accountType){
     }
}

Data Binding and Security concerns
def p = Person.get(1)
p.properties['firstName', 'lastName'] = params

In this case, only the firstName and lastName properties will be bound.

Or, we can exclude some params

def p = new Person()
bindData(p, params, [exclude: 'dateOfBirth'])

Or, including some certain properties:

def p = new Person()
bindData(p, params, [include: ['firstName', 'lastName']])

7.1.7 XML and JSON Responses
Using the render method to output XML
def list(){
     def results = Book.list()
     render(contentType: "text/xml") {
          books {
               for (b in results){
                    book(title: b.title)
               }
          }
     }
}

<books>
     <book title="The Stand" />
     <book title="The God" />
</books>

Using the render method to output JSON
def list(){
     def results = Book.list()
     render(contentType: "text/json"){
          books = array {
               for(b in results){
                    book title: b.title
               }
          }
     }
}

[
     {title: "The Stand"},
     {title: "The God"}
]

Automatic XML Marshalling
import grails.converters.*
render Book.list() as XML

Or

def xml = Book.list().encodeAsXML()
render xml

Automatic JSON Marshalling
render Book.list(0 as JSON

Or encodeAsJSON

7.1.8 More on JSONBuilder

7.1.9 Uploading Files
Programmatic File Uploads
Grails supports file uploads using Spring's MultipartHttpServletRequest interface.
Upload Form: <br />
<g:uploadForm action="upload">
     <input type="file" name="myFile" />
     <input type="submit" />
</g:uploadForm>

uploadForm tag conveniently adds the enctype="multipart/form-data"

def upload(){
     def f = request.getFile('myFile')
     if(f.empty) {
          flash.message = 'file cannot be empty'
          render(view: 'uploadForm')
          return
     }
     f.transferTo(new File('/some/local/dir/myfile.txt'))
     response.sendError(200,'Done')
}

File Uploads through Data Binding
class Image {
     byte[] myFile
    
     static constraints = {
          myFile maxSize: 1024 * 1024 *2
     }
}

def img = new Image(params)

7.1.10 Command Objects
7.1.11 Handling Duplicate Form Submissions
<g:form useToken="true" …>

withForm {
     //good request
}.invalidToken {
     //bad request
}

<g:if test="${flash.invalidToken}" >
     Don't click the button twice!
</g:if>

7.1.12 Simple Type Converters
Type Conversion Method
def total = params.int('total')

def total = params.int('total', 42)

Handling Multi Parameters
for (name in params.list('name')){
     println name
}

References:
http://grails.org/doc/latest/guide/index.html
http://grails.org/doc/latest/guide/theWebLayer.html#redirectsAndChaining


分享到:
评论

相关推荐

    基于java+springboot+mysql+微信小程序的流浪动物救助小程序 源码+数据库+论文(高分毕业设计).zip

    项目已获导师指导并通过的高分毕业设计项目,可作为课程设计和期末大作业,下载即用无需修改,项目完整确保可以运行。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载 技术组成 语言:java 开发环境:idea、微信开发者工具 数据库:MySql5.7以上 部署环境:maven 数据库工具:navicat

    基于springboot的体质测试数据分析及可视化设计源码(java毕业设计完整源码+LW).zip

    项目均经过测试,可正常运行! 环境说明: 开发语言:java JDK版本:jdk1.8 框架:springboot 数据库:mysql 5.7/8 数据库工具:navicat 开发软件:eclipse/idea

    python 3.8.20 windows install 安装包

    编译的 python 3.8.20 windows install 安装包

    基于go-zero的用户管理系统全部资料+详细文档.zip

    【资源说明】 基于go-zero的用户管理系统全部资料+详细文档.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

    基于springboot的时间管理系统源码(java毕业设计完整源码+LW).zip

    时间管理系统采用java技术,基于springboot框架,mysql数据库进行开发,实现了首页,个人中心,系统公告管理,用户管理,时间分类管理,事件数据管理,目标数据管理,用户日记管理等内容进行管理。 环境说明: 开发语言:java JDK版本:jdk1.8 框架:springboot 数据库:mysql 5.7/8 数据库工具:navicat 开发软件:eclipse/idea

    基于springboot的火车订票管理系统源码(java毕业设计完整源码+LW).zip

    项目均经过测试,可正常运行! 环境说明: 开发语言:java JDK版本:jdk1.8 框架:springboot 数据库:mysql 5.7/8 数据库工具:navicat 开发软件:eclipse/idea

    收到防护服快快快啊啊啊啊啊

    收到防护服快快快啊啊啊啊啊

    葡萄城手册,快速上手,灵活报表

    制作报表

    simulink相位调制器PM

    simulink相位调制器PM

    2023-04-06-项目笔记 - 第三百六十阶段 - 4.4.2.358全局变量的作用域-358 -2025.12.27

    2023-04-06-项目笔记-第三百六十阶段-课前小分享_小分享1.坚持提交gitee 小分享2.作业中提交代码 小分享3.写代码注意代码风格 4.3.1变量的使用 4.4变量的作用域与生命周期 4.4.1局部变量的作用域 4.4.2全局变量的作用域 4.4.2.1全局变量的作用域_1 4.4.2.358局变量的作用域_358- 2024-12-27

    (59423620)指纹识别基于matlab GUI指纹识别【含Matlab源码 1353期】.zip

    【指纹识别】基于matlab GUI指纹识别是一种生物特征识别技术,它利用了人类指纹的唯一性和稳定性进行身份验证。在本项目中,我们探讨的是如何使用MATLAB图形用户界面(GUI)来实现这一过程,包括图像采集、预处理、特征提取和匹配等多个步骤。 指纹图像的采集是整个系统的基础。这通常通过专用的指纹传感器完成,它们可以捕获高质量的指纹图像。在MATLAB中,我们可以使用摄像头或其他图像输入设备模拟这一过程,将捕获的图像导入到GUI中。 接下来是预处理阶段。指纹图像往往含有噪声和不清晰的部分,因此需要进行图像增强,以突出指纹的细节特征,如脊线和谷线。这可能包括二值化、直方图均衡化、滤波等操作。MATLAB的图像处理工具箱提供了丰富的函数支持这些预处理步骤。 特征提取是识别的核心环节。指纹的特征通常包括核心点、三角点、终结点以及脊线的方向和纹路模式。MATLAB中可以使用方向图像和细化算法来检测这些特征点,并生成特征描述符。例如,使用Gabor滤波器可以提取脊线方向信息,而细化算法可以帮助找到特征点。 GUI设计是用户交互的关键。在这里,用户可以上传指纹图像,系统会实时显示预处理和特征提取的

    基于Go后端的外挂式评论系统全部资料+详细文档.zip

    【资源说明】 基于Go后端的外挂式评论系统全部资料+详细文档.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

    nosql分布式数据库期末考试题a.docx

    ### NoSQL分布式数据库知识点解析 #### 一、选择题知识点详解 **1. 关系数据库与非关系数据库** - **关系数据库**: MySQL、SQL Server 和 Oracle 均属于关系数据库,它们采用 SQL 作为标准查询语言,支持 ACID 特性(原子性、一致性、隔离性和持久性)。 - **非关系数据库**: 指的是不采用表格形式来组织数据的数据库类型,通常用于处理大量非结构化或半结构化数据。 **2. 数据库语言分类** - **数据定义语言 (DDL)**: 用于定义数据库结构的语言,如创建、修改和删除表等操作。 - **数据操纵语言 (DML)**: 用于添加、修改和删除数据的语言,如 INSERT、UPDATE 和 DELETE 等命令。 - **数据查询语言 (DQL)**: 用于查询数据的语言,主要是 SELECT 语句。 - **数据控制语言 (DCL)**: 用于管理权限和安全性的语言,如 GRANT 和 REVOKE 命令。 **3. 关系数据库优点** - **易于理解**: 使用表格形式组织数据,符合人类直观认知习惯。 - **易于维护**: 支持事务处理,确保数据一致性。 - **支持 SQL**: 使用标准查询语言,便于数据查询和处理。 **4. MongoDB 编程语言** - **JavaScript**: MongoDB 是用 C++ 开发的,但其 Shell 环境使用 JavaScript,使得数据查询和管理更加便捷。 **5. NoSQL 数据库特点** - **分布式**: 能够在多台计算机上分布存储数据,适用于大数据量的处理。 - **不基于 ACID**: 相对于传统的关系数据库,NoSQL 数据库往往牺牲了部分 ACID 特性以换取更高的性能和可扩展性。 **6. CAP 理论** - **一致性 (C)**: 所有节点在同一时间具有相同的数据。 - **可用性 (A)**: 每个请求都能得到一个合理的时间内非错误的响应,但不保证是最新的数据。 - **分区容错性 (P)**: 系统中任意信息丢失的子网故障都不会导致整个系统不可用。 - **CAP 定理**: 在一个分布式系统中,只能同时满足一致性、可用性和分区容错性中的两个。 **7. 知识图谱与 NoSQL 数据库** - **MongoDB**: 适合用于构建知识图谱,因为它支持灵活的数据模型和高效的查询能力。 - **Redis**: 一种键值存储数据库,适用于缓存和实时数据分析。 - **HBase**: 一种列族存储数据库,适合大规模随机读写访问。 **8. HBase 特点** - **容量巨大**: 可以存储非常大量的数据。 - **列存储**: 数据按列族存储,方便进行列级别的访问。 - **稀疏性**: 允许某些列未填充,即某些单元格为空。 **9. HBase 核心组件** - **HMaster**: 负责协调客户端请求、分配 Region 以及负载均衡等工作。 - **RegionServer**: 存储数据的实际服务器。 - **Zookeeper**: 用于协调分布式环境中的服务,例如选举 HMaster。 **10. MongoDB 集合命名规则** - **system.**: 系统保留前缀,用于系统集合。 - **保留字符 $**: 用于特殊目的,如聚合管道。 - **空字符串**: 不允许作为集合名称。 **11. MongoDB 主键** - **UUID**: 通用唯一识别码,常用于作为主键。 - **Sequence**: 序列,也可以作为主键生成方式之一。 - **Auto-increment**: 自动递增,MongoDB 默认为主键使用 BSON 类型的 ObjectId。 **12. MongoDB 逻辑结构** - **数据库 (db)**: MongoDB 中的最高层级,可以包含多个集合。 - **集合 (collection)**: 数据库内的数据容器,类似于关系数据库中的表。 - **文档 (document)**: 数据的基本单位,由键值对组成。 **13. 内存数据库** - **Redis**: 键值存储数据库,常作为内存数据库使用。 - **MongoDB**: 非内存数据库,但可以通过配置将常用数据驻留在内存中。 - **Bigtable**: 谷歌的分布式数据存储系统,并非专门设计为内存数据库。 **14. Neo4j 图形数据库应用场景** - **快递物流数据管理**: 适用于关系较为复杂的数据管理场景。 - **家庭用电数据管理**: 更偏向于使用时序数据库。 - **企业考勤数

    双工位多吸嘴龙门式取放模块proe5.0可编辑全套技术资料100%好用.zip

    双工位多吸嘴龙门式取放模块proe5.0可编辑全套技术资料100%好用.zip

    主持稿22222222222

    主持稿22222222222

    基于ssm的模拟麦当劳点餐系统全部资料+详细文档.zip

    【资源说明】 基于ssm的模拟麦当劳点餐系统全部资料+详细文档.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

    php.html.mysql.zip

    php.html.mysql.zip

    Java 入门教程.md

    Java 入门教程.md

    CD668cb芯片电路图

    CD668cb芯片电路图

    基于C语言课程设计大作业 - 马里奥游戏、详细文档+全部资料+高分项目.zip

    【资源说明】 基于C语言课程设计大作业 - 马里奥游戏、详细文档+全部资料+高分项目.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

Global site tag (gtag.js) - Google Analytics