为什么我不能获得HAL支持在grails 2.3.8中工作?

时间:2014-06-05 23:02:21

标签: rest grails hateoas

我按照文档中的说明进行操作:

http://grails.org/doc/2.3.8/guide/webServices.html#hypermedia

为什么grails不会产生HAL格式的输出,如文档中所示?

我有一个使用@Resource注释映射的域对象:

@Resource(uri='/documentCatalogs', formats = ['json', 'xml'], readOnly = true)
class DocumentCatalog {
    String entityType
    String actionCode
    ...
}

...在我的conf / spring / resources.groovy中,我配置了HAL JSON渲染器bean:

import com.cscinfo.platform.api.formslibrary.DocumentCatalog
import grails.rest.render.hal.HalJsonCollectionRenderer
import grails.rest.render.hal.HalJsonRenderer

// Place your Spring DSL code here
beans = {
    halDocumentCatalogRenderer(HalJsonRenderer, DocumentCatalog)
    halDocumentCatalogCollectionRenderer(HalJsonCollectionRenderer, DocumentCatalog)
}

使用调试器,我确认调用了HalJsonRenderer上的initialize()方法,并使用正确的targetType构造它。

我使用Postman发送了一个休息电话:

http://localhost:8080/formslibrary/documentCatalogs/3
Accept application/hal+json

我得到的回复是常规JSON,不包含任何链接:

{
    "class": "com.cscinfo.platform.api.formslibrary.DocumentCatalog",
    "id": 3,
    "actionCode": "WITH",
    "entityType": "LLP",
...
}

我错过了什么?是否有一些插件或配置设置我必须启用此行为?是否有一些未记录的附加映射属性?

1 个答案:

答案 0 :(得分:7)

想出来!修复有多个方面......

我不得不在@Resource注释中添加“hal”作为列出的格式之一:

@Resource(uri='/documentCatalogs', formats = ['json', 'xml', 'hal'])

调试器中的一些搜索显示,Grails将根据从客户端发送的UserAgent字符串轻率地忽略Accept标头。 (就我而言,因为我使用的是Postman,它是Google Chrome UA字符串。)

Accept标题问题的一种解决方法是在网址末尾添加“.hal”:

http://localhost:8080/formslibrary/documentCatalogs/3.hal

这不是一个非常好的IMO解决方案,因为渲染器生成的HAL URL默认不以“.hal”结尾。

更好的解决方案是通过更新配置来修复Grails对accept头的处理。在Config.groovy中,您会看到一行说:

grails.mime.disable.accept.header.userAgents = ['Gecko', 'WebKit', 'Presto', 'Trident']

将其更改为:

grails.mime.disable.accept.header.userAgents = ['None']

这会强制Grails遵守Accept标头,无论用户代理如何。

希望这可以帮助那些遇到同样问题的人。

P.S。在ResponseMimeTypesApi#getMimeTypesFormatAware(...)方法中设置断点非常有用。