The Web Layer

本文深入讲解Grails框架中的控制器概念,包括如何创建控制器及其动作、处理请求和响应的方法、使用模型与视图进行数据展示的技术细节等。
The Web Layer
一个控制器要"处理请求(handles request)","创建或准备响应(response)","判断请求的范围"。
从另外一个方面讲,每个响应都会创建一个新的控制器。一个控制器能够产生响应(response)或者代理生成一个页面(view)。
创建一个控制器很简单。他的名称以Controller 结尾,还有把他放在grails/controller的目录下。


理解Controllers和Actions
创建Controller
在项目的根目录使用create-controller [name]命令创建。
grails create-controller book
class BookController { … }


创建一个actions
一个控制器的属性每一个都是代码块。每个属性的名称映射一个uri。
class BookController {
def list = { // do controller logic
// create model return model
}
}
URI是/root/book/list

默认的Action
有几个规则:
当action中没有定义明确的uri,你定义一个index属性,所有的请求将由它处理。
要么你就明确定义defaultAction 属性
def defaultAction = "list"

控制器和范围(scopes)
*servletContext javax.servlet.ServletContext
*session HttpSession
*request HttpServletRequest
*params 从CGI引入的一个参数
*flash

访问这些变量
def find = {
def findBy = params["findBy"]
def appContext = request["foo"]
def loggedUser = session["logged_user"] }
class BookController {
def find = {
def findBy = params.findBy
def appContext = request.foo
def loggedUser = session.logged_user }
}

使用Flash scope
flash是一个临时的存储变量,仅仅在两个request之间传递。

Models和视图
模型本质就是一个map,在返回时候,给view层使用。
有以下几种方式放回一个map的实例
def show = {
[ book : Book.get( params.id ) ]
}

class BookController {
List books
List authors
def list = {
books = Book.list()
authors = Author.list()
}
}
上面这些代码是线程不安全的。
使用Spring ModeAndView
import org.springframework.web.servlet.ModelAndViewdef index = {
def favoriteBooks = … // get some books just for the index page, perhaps your favorites // forward to the list view to show them
return new ModelAndView("/book/list", [ bookList : favoriteBooks ])
}

选择视图:
class BookController {
def show = {
[ book : Book.get( params.id ) ]
}
}
上面的代码并没有明确指定返回的视图,Grails怎么知道的了?是因为grails使用了约定。
grails将会自动查找grails-app/views/book/show.gsp(而实际上它会先查找jsp,因为grails 能够使用jsp)

如果你喜欢指定返回的页面和模型(render):
def show = {
def map = [ book : Book.get( params.id ) ]
render(view:"display", model:map)
}
定位在grails-app/views/book/display.gsp
这里默认的会查找book/display.gsp
如果想让它返回其他页面,看下面代码
def show = {
def map = [ book : Book.get( params.id ) ]
render(view:"/shared/display", model:map)
}
定位在grails-app/views/shared/display.gsp
返回一个简单的response
render "Hello World!"
// write some markup
render {
for(b in books) {
div(id:b.id, b.title)
}
}
// render a specific view
render(view:'show')
// render a template for each item in a collection
render(template:'book_template', collection:Book.list())
// render some text with encoding and content type
render(text:"<xml>some xml</xml>",contentType:"text/xml",encoding:"UTF-8")


Redirects 和 chaining
class OverviewController {
def login = {} def find = {
if(!session.user)
redirect(action:login)

}
}

redirect使用的是HttpServeltResponse
在同一个控制类中:
redirect(action:login)
在不同的action中
redirect(controller:'home',action:'index')
URI
redirect(uri:"/login.html")
url
redirect(url:"http://grails.org")
HTTP/2 Framing Layer(帧层)是HTTP/2协议的核心组成部分,它对HTTP/2的性能提升和功能实现起到了关键作用。 ### 基本概念 HTTP/2 Framing Layer是位于HTTP/2协议栈中的底层部分,它负责将HTTP消息(如请求和响应)分割成更小的帧(Frame)进行传输,并在接收端将这些帧重新组装成完整的消息。这种基于帧的传输方式使得HTTP/2能够更高效地利用网络带宽,提高传输性能。 ### 帧的结构 每个HTTP/2帧都有一个固定的9字节头部,包含以下字段: - **长度(Length)**:3字节,指示帧负载的长度,最大值为2^24 - 1字节。 - **类型(Type)**:1字节,定义帧的类型,如DATA、HEADERS等。不同的帧类型具有不同的功能。 - **标志(Flags)**:1字节,用于传递与帧相关的额外信息,如是否为最后一帧等。 - **流标识符(Stream Identifier)**:4字节,用于标识该帧所属的流。流是HTTP/2中一个逻辑上的概念,代表客户端和服务器之间的双向通信通道。 在9字节头部之后是帧的负载部分,其内容根据帧的类型而定。 ### 帧的类型 HTTP/2定义了多种帧类型,常见的有以下几种: - **DATA帧**:用于传输HTTP消息的实际数据,如请求或响应的主体内容。 - **HEADERS帧**:用于传输HTTP消息的头部信息,如请求头或响应头。 - **PRIORITY帧**:用于设置或更新流的优先级。 - **RST_STREAM帧**:用于终止一个流,通常表示流出现错误或需要取消。 - **SETTINGS帧**:用于在客户端和服务器之间交换配置信息,如最大并发流数等。 ### 流和多路复用 HTTP/2的Framing Layer支持多路复用,即多个流可以在同一个TCP连接上并行传输,而不会相互干扰。每个流由一个唯一的流标识符标识,不同流的帧可以交错传输。这使得客户端和服务器可以同时处理多个请求和响应,避免了HTTP/1.x中串行传输带来的“队头阻塞”问题。 ### 示例代码(使用Python的hyper库) ```python import hyper # 创建一个HTTP/2连接 conn = hyper.HTTP20Connection('example.com') # 发起一个请求 stream_id = conn.request('GET', '/') # 获取响应 resp = conn.get_response(stream_id) # 读取响应数据 data = resp.read() print(data) ``` ### 安全性和可靠性 HTTP/2 Framing Layer还提供了一些机制来确保传输的安全性和可靠性。例如,通过设置标志位可以指示帧的完整性和顺序,以及是否为最后一帧。此外,RST_STREAM帧可以用于处理错误和异常情况,保证流的正常关闭。 ### 与HTTP/1.x的比较 与HTTP/1.x相比,HTTP/2的Framing Layer有以下优势: - **多路复用**:避免了“队头阻塞”,提高了并发性能。 - **头部压缩**:使用HPACK算法对HTTP头部进行压缩,减少了头部信息的传输量。 - **二进制分帧**:采用二进制格式传输帧,比HTTP/1.x的文本格式更高效,易于解析和处理。 综上所述,HTTP/2 Framing Layer通过引入帧的概念和多路复用机制,显著提高了HTTP协议的性能和效率,为现代Web应用的发展提供了有力支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值