我正在尝试在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/

10-11 22:52
查看更多