我正在尝试在Grails中实现自定义编码器。这是编码员:
class AdultPlanningMarshaller implements ObjectMarshaller<JSON> {
boolean supports(Object theObject)
{
return theObject instanceof AdultPlanning
}
void marshalObject(Object theObject, JSON theConverter)
{
AdultPlanning adult = (AdultPlanning)theObject
JSONWriter writer = theConverter.getWriter()
writer.object()
writer.key('id').value(adult.id)
...
writer.endObject()
}
}
我正在bootstrap.groovy中注册它,当我运行集成测试时,supports方法会正确触发,并且使用正确的对象和JSON对象调用marshalObject方法。
当我点击:
writer.object()
调用时,将引发异常:
org.codehaus.groovy.grails.web.json.JSONException: Misplaced object: expected mode of INIT, OBJECT or ARRAY but was DONE
因此看来作者已经完成了一些工作,但我不知道该做什么。
关于JSON编码器的文档并不多,示例也很少,但是我想我做对了,但是肯定没有用。任何提示将不胜感激。
尽管由于某些原因断点仅在第二次调用中发生,但与调试器的进一步合作似乎表明该对象marshaller被调用了两次。第一次通过它似乎工作得很好,因为当断点确实起作用时,我通过ConConverter.getWriter()获得的JSONWriter已正确编码了对象的JSON。这是第二次调用,因为该对象已经被编码,并且JSONWriter不再处于“init”状态,这是第二次调用。显然没有什么可用来区分两次调用之间的区别,但是为什么编码程序被两次调用?
根据要求,这里是 Controller 。触发的显示操作是:
class PrimaryController extends RestfulController implements AlwaysRenderJsonException {
def springSecurityService
def familyService
static responseFormats = ['json']
PrimaryController() {
/*
* Tell the base class the name of the resource under management.
*/
super(Primary)
}
@Override
protected Primary createResource() {
//def instance = super.createResource()
//TODO: Should be able to run the above line but there is an issue GRAILS-10411 that prevents it.
// Code from parent is below, as soon as the jira is fixed, remove the following lines:
Primary instance = resource.newInstance()
bindData instance, this.getObjectToBind()
//Code from super ends here
def family = familyService.safeGetFamily(params.long('familyId'))
familyService.addAdultToFamily(instance, family) // Add the primary member to the family.
return instance
}
/**
* Deletes a resource for the given id
* @param id The id
*/
@Override
def delete() {
if(handleReadOnly()) {
return
}
Child instance = queryForResource(params.id)
if (instance == null) {
notFound()
return
}
/*
* Because of the multiple belongsTo relationships of events, you have to get rid of all
* the events and make the profiles consistent BEFORE deleting the person instance.
*/
instance.removePerson()
request.withFormat {
'*'{ render status: NO_CONTENT } // NO CONTENT STATUS CODE
}
}
@Override
protected List<Primary> listAllResources(Map params) {
if (params.familyId == null)
{
throw new ESPException("params.familyId may not be null")
}
def user = springSecurityService.loadCurrentUser()
return \
AdultPlanning.where {
family.id == params.familyId \
&& family.user == user \
&& typeOfPerson == PeopleTypeEnum.PRIMARY
}.list()
}
@Override
protected Primary queryForResource(Serializable id) {
def inst = familyService.safeGetAdult(Long.parseLong(id), params.long('familyId'))
/*
* It was safe to access the requested id, but the requested id may NOT be a primary
* so we need to check.
*/
return (inst instanceof Primary ? inst : null)
}
/**
* Show the primary for the specified family.
*
* @return
*/
@Override
def show() {
Primary primary = familyService.safeGetFamily(params.long('familyId'))?.primary
respond primary
}
}
触发它的集成测试:
void "We should be able to show a primary."() {
given:
family.addToAdults(new Primary(firstName: "Barney"))
family.save()
family.adults.each { it.save() }
when:
controller.response.reset()
resetParameters(controller.params, [familyId: family.id])
controller.request.method = 'GET'
controller.show()
then:
1 * mSpringSecurityService.loadCurrentUser() >> user
controller.response.json
controller.response.json.firstName == "Barney"
}
最佳答案
好吧,这很尴尬。
我将IntelliJ用作Java / Groovy IDE。今天早上我有与工作相关的事情要做,然后退出IntelliJ。当我重新启动IntelliJ时,已经完全可重现的上述问题不再发生,并且在所有情况下都生成了适当的JSON。
因此,似乎IntelliJ状态某种程度上已损坏,重新启动后将其清除了。
问题解决了。
我猜。
感谢您的帮助/建议。
关于json - 无法实现Grails ObjectMarshaller <JSON>的实现,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27659392/