我目前有以下3个域类:
User.groovy
class User { ... static hasMany = [ ... ] static belongsTo = [ course : Course, university : University ] }
Course.groovy
class Course { String title static hasMany = [ universities : University, users : User ] static belongsTo = University }
大学
class University { String name static hasMany = [ courses : Course, users : User ] }
我使用以下代码收集了大学的所有课程:
def courses = Course.withCriteria { universities { eq('id', Long.parseLong(params.universityId)) } } render courses as JSON
带有这样的示例响应:
[{ "class":"classifieds.Course", "id":1, "title":"Computer Science", "universities": [{"class":"University", "id":1}], "users": [{"class":"User" ,"id":1}] }]
我的问题是,我想将响应范围限制为不包括users 或universities当前正在返回的值,而只courses返回要在JSON中返回的列表。如何限制呢?
users
universities
courses
Course在引导程序中注册所需的JSON对象编组器,如下所示:
Course
//Bootstrap def init = { servletContext -> JSON.registerObjectMarshaller(Course){ def returnObj = [:] returnObj.id = it.id returnObj.title = it.title returnObj } }
上面的寄存器仅返回Course转换并呈现为JSON时的字段。请注意,这将永久封送Course,以仅返回其字段,而不返回其关联。如果暂时需要,那么您可以很好地遵循蒂姆的方法。
如果要使其对所有字段通用,则:
JSON.registerObjectMarshaller(Course){course -> def fields = grailsApplication.domainClasses .find{it.name == 'Course'} .properties .findAll{!it.association} .name - 'version' //Remove version if req. return fields.collectEntries{[it, course."$it"]} }
提供grailsApplication注入Bootstrap.groovy
grailsApplication
Bootstrap.groovy
另外,如果不是要修改JSON的构建方式,而是要调和标准结果,则可以使用projections来获取所需的内容property:
projections
property
def courses = Course.withCriteria { universities { eq('id', Long.parseLong(params.universityId)) } projections{ property('id') property('title') } }
更新: 为了检索作为映射实体的结果,那么我将按照此处所示遵循HQL或使用createCriteria并将结果转换为映射,如下所示(未经测试):
createCriteria
import org.hibernate.transform.Transformers def criteria = Course.createCriteria() criteria.resultTransformer(Transformers.ALIAS_TO_ENTITY_MAP) def courses = criteria.list { universities { eq('id', Long.parseLong(params.universityId)) } projections{ property('id') property('title') } }
我不确定属性名称会创建别名。我遇到任何问题,都可以快速回退到HQL查询。