1.建立Controller
①建立一个空的Controller,输入框里输入名称(系统自动在其名字后加上Controller)
②生成一个普通增删改的controller,不带GSP,输入框里输入domain的类全名
③生成增删改查的controller,带gsp,输入框里输入domain的类全名。
若选①,则生成出这样一个Controller:
package edu.ming class TestCController { def index() { } }
index是默认的方法,访问controller的格式如下:
/$controller/$action
$controller 是controller的名字,就是类短名里Controller之前的那那部分,如上例中,URL为 /TestC,首字母小写亦可,如 /testC,非首字母则区分大小写
$action 故名思意,是action,也就是里面的方法。上例中index的访问URL是 /TestC/index ,不过index是默认的方法,如果未指明会默认指向该方法,所以上述可简写为 : /TestC
当然你也可以更改默认访问的方法,在controller里加上一句代码即可,如,默认转到myhome方法:
static defaultAction = "myhome"
可以看到,建立controller以后在views目录里已经用controller的名称建立了一个文件夹,这里在里面建立一个GSP:
gsp的默认命名规则:只要和action的名称一样就默认转发。如我们新建一个index.gsp,上例中的controller的index方法执行完成后会转向这个gsp。
GSP代码:
<%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta name="layout" content="main"/> <title>这是我的首页</title> </head> <body> <div class="body"> 我是一个首页 </div> </body> </html>
注:以上是新建过程中选择使用gsp模板生成的。
启动app:
启动完成后访问:
http://localhost:8080/grailsTest/testC
可以看到结果
2.controller里常用的方法
获取GET或POST参数:
def name = params["name"]
获取request对象
def name = request["name"]
获取session对象
def name = session["name"]
在其他方法里重定向到myhome方法
redirect(action:myhome)
直接转发对象到gsp(会将对象转换为map,转发到gsp上)
[person: new Person(name:"Jack")]
转发到指定gsp
def myhome() { def attributes = [person: new Person(name:"Jack")] render(view: "index", model: attributes) }
render是个很有用的方法,如果你想做一个web接口,不需要gsp,可以直接这样
def myhome() { render "a,b,c" }
其他强大的用法不细细列举了。
3.GSP和view
gsp和jsp感觉上差不多,都是html+动态语言+EL表达式+标签库
一个带脚本的gsp:
<!doctype html> <html> <head> <title>Grails</title> </head> <body> <% out << "我是用Groovy写出来的" %> </body> </html>
和jsp一样写在<%和%>之间,当然不推荐用这种方式,有可能的话还是尽量用标签库和el表达式。
来试一下模板的用法。
在刚刚views的testC目录,建一个模板文件,模板文件需要下划线开头。建一个_houseView.gsp,内容如下:
<div> <div>名字: ${house?.name}</div> <div>类型: ${house?.type}</div> </div>
在TestController里加些代码,让它往gsp里转发些数据:
package edu.ming import test.domain.House; class TestCController { def index() { [house:new House(name:"Jack's Home",type:"common")] } }
在index.gsp里引入模板:
<%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta name="layout" content="main"/> <title>这是我的首页</title> </head> <body> <div class="body"> 我是一个首页 <g:render template="houseView" model="[house: house]" /> </div> </body> </html>
运行,结果:
模板的用法感觉跟标签库差不多,不过可以在gsp里写html标签还是比在groovy代码里写html感觉要来得直接,更舒服一些。
这个方法把模板文件放在了controller的目录里面。如果想全局重用的话可以规划一个目录,如views/tmpl/_houseView.gsp
index.gsp在引用模板之前加一句:
<g:render template="/tmpl/houseView" />
然后再来看一下页面组织,grails采用了sitemesh框架。
其实应该有感觉,看一下现在testC里的index.gsp,里面没写header和footer,但是已经默认被加上了。注意这句:
<meta name="layout" content="main"/>
这句意思是说,使用main这个layout。这个layout在views/layouts里面,可以找到 main.gsp ,打开看到如下内容:
<!doctype html> <!--[if lt IE 7 ]> <html lang="en" class="no-js ie6"> <![endif]--> <!--[if IE 7 ]> <html lang="en" class="no-js ie7"> <![endif]--> <!--[if IE 8 ]> <html lang="en" class="no-js ie8"> <![endif]--> <!--[if IE 9 ]> <html lang="en" class="no-js ie9"> <![endif]--> <!--[if (gt IE 9)|!(IE)]><!--> <html lang="en" class="no-js"><!--<![endif]--> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title><g:layoutTitle default="Grails"/></title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="shortcut icon" href="${resource(dir: 'images', file: 'favicon.ico')}" type="image/x-icon"> <link rel="apple-touch-icon" href="${resource(dir: 'images', file: 'apple-touch-icon.png')}"> <link rel="apple-touch-icon" sizes="114x114" href="${resource(dir: 'images', file: 'apple-touch-icon-retina.png')}"> <link rel="stylesheet" href="${resource(dir: 'css', file: 'main.css')}" type="text/css"> <link rel="stylesheet" href="${resource(dir: 'css', file: 'mobile.css')}" type="text/css"> <g:layoutHead/> <r:layoutResources /> </head> <body> <div id="grailsLogo" role="banner"><a href="http://grails.org"><img src="${resource(dir: 'images', file: 'grails_logo.png')}" alt="Grails"/></a></div> <g:layoutBody/> <div class="footer" role="contentinfo"></div> <div id="spinner" class="spinner" style="display:none;"><g:message code="spinner.alt" default="Loading…"/></div> <g:javascript library="application"/> <r:layoutResources /> </body> </html>
看到body里面有刚刚看到的header和footer的定义。那么这个 <g:layoutBody/> 就是testC/index.gsp的body内容,<g:layoutTitle default="Grails"/> 自然就是标题的定义,如果没定义他默认就是Grails,<g:layoutHead/> 这个就是index.gsp的head了。通过修改这个文件可以更改全局的样式。