我按照文档中的说明进行操作:
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",
...
}
我错过了什么?是否有一些插件或配置设置我必须启用此行为?是否有一些未记录的附加映射属性?
答案 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(...)
方法中设置断点非常有用。