如何创建 Grails HAL 转换器
How to create a Grails HAL converter
我知道有一个 HalJsonRenderer,但我想知道是否有一种方法可以拥有类似 JSON 转换器的东西,以便能够执行以下操作:
render MyObject as HAL
"as" 运算符...它是如何工作的?
如果添加可选的括号,render ... as JSON
会更清楚:
render(foo as JSON)
render 方法有一些重载,其中之一接受 JSON,所以棘手的部分是 foo as JSON
。
Groovy 通过将每个运算符与实际执行工作的方法配对,使重载运算符变得简单。 ==
运算符是通过调用 equals
方法实现的(或者 compareTo
如果 class 实现了 Comparable
,<<
运算符调用 leftShift
, 等等 This archived page 有很好的 table 运算符及其相应的方法(Groovy 站点最近进行了重大检修,这个页面似乎在随机播放中丢失了)。
as
在技术上不是运算符,但它的处理方式类似。如果您添加一个 asType
方法,它将被调用以使 class 有机会将自身转换为请求的类型:
Object asType(Class c) { ... }
Grails 连接 as JSON
和 as XML
的方式相当复杂,但重要的部分涉及向所有控制器添加 asType
方法(除了 render
, redirect
, getParams
(以及相应的 params
属性)等)此方法然后转换为 JSON 或 XML ,或者如果目标 class 不是 JSON 或 XML.
,则执行传统的 cast/conversion
我认为直接支持它会比它值得做的更多工作,所以如果是我,我会在服务中创建一个方法来完成将支持的类型转换为 HAL 并呈现它的工作,比如
class SomeService {
String asHal(foo) {
...
}
}
然后你可以从你的控制器调用它:
class SomeController {
def someService
def anAction() {
...
def foo = ...
render someService.asHal(foo)
}
}
这不像 render as HAL
那样方便,但它的工作量并不多,而且好处是不那么神奇。
要支持 render foo as HAL
,您需要向任何 class foo
添加一个 asType
方法,或者做类似于 Grails 为 [=64 做的事情=] 和 XML。添加一个 asType
方法可能是不切实际的,特别是如果你想支持多种类型,如果这些类型像 ArrayList 一样预先存在 class 则更是如此。您可以像 JSON 和 XML class 那样实现 org.codehaus.groovy.grails.web.converters.Converter
接口(查看支持代码,您实际上需要扩展 org.codehaus.groovy.grails.web.converters.AbstractConverter
),并且创建相关的支持 classes 来进行转换(这一切都被设计为可扩展的,尽管我认为我没有看到有人这样做)。这会很有趣,而且可能是一次很好的学习经历,但正如我所说 - 考虑到更直接的实施是多么简单,工作量远远超过它的价值。
我知道有一个 HalJsonRenderer,但我想知道是否有一种方法可以拥有类似 JSON 转换器的东西,以便能够执行以下操作:
render MyObject as HAL
"as" 运算符...它是如何工作的?
如果添加可选的括号,render ... as JSON
会更清楚:
render(foo as JSON)
render 方法有一些重载,其中之一接受 JSON,所以棘手的部分是 foo as JSON
。
Groovy 通过将每个运算符与实际执行工作的方法配对,使重载运算符变得简单。 ==
运算符是通过调用 equals
方法实现的(或者 compareTo
如果 class 实现了 Comparable
,<<
运算符调用 leftShift
, 等等 This archived page 有很好的 table 运算符及其相应的方法(Groovy 站点最近进行了重大检修,这个页面似乎在随机播放中丢失了)。
as
在技术上不是运算符,但它的处理方式类似。如果您添加一个 asType
方法,它将被调用以使 class 有机会将自身转换为请求的类型:
Object asType(Class c) { ... }
Grails 连接 as JSON
和 as XML
的方式相当复杂,但重要的部分涉及向所有控制器添加 asType
方法(除了 render
, redirect
, getParams
(以及相应的 params
属性)等)此方法然后转换为 JSON 或 XML ,或者如果目标 class 不是 JSON 或 XML.
我认为直接支持它会比它值得做的更多工作,所以如果是我,我会在服务中创建一个方法来完成将支持的类型转换为 HAL 并呈现它的工作,比如
class SomeService {
String asHal(foo) {
...
}
}
然后你可以从你的控制器调用它:
class SomeController {
def someService
def anAction() {
...
def foo = ...
render someService.asHal(foo)
}
}
这不像 render as HAL
那样方便,但它的工作量并不多,而且好处是不那么神奇。
要支持 render foo as HAL
,您需要向任何 class foo
添加一个 asType
方法,或者做类似于 Grails 为 [=64 做的事情=] 和 XML。添加一个 asType
方法可能是不切实际的,特别是如果你想支持多种类型,如果这些类型像 ArrayList 一样预先存在 class 则更是如此。您可以像 JSON 和 XML class 那样实现 org.codehaus.groovy.grails.web.converters.Converter
接口(查看支持代码,您实际上需要扩展 org.codehaus.groovy.grails.web.converters.AbstractConverter
),并且创建相关的支持 classes 来进行转换(这一切都被设计为可扩展的,尽管我认为我没有看到有人这样做)。这会很有趣,而且可能是一次很好的学习经历,但正如我所说 - 考虑到更直接的实施是多么简单,工作量远远超过它的价值。