开发者

UrlMappings parseRequest:true causes JSON Exception when nothing to parse

UPDATE: Just found this bug that looks like my issue.

I'm playing around with a client side framework that works on pure JSON. I have a UrlMapping as:

"/books/$id?"(controller:'book', parseRequest:true) {
    action = [GET:'show',PUT:'update', POST:'save']
}

The problem is with the 'show' action in that if there is no id passed into the request, I simply return a JSON list of all the books:

def show = {
    if (params.id) {
      def bookInstance = Book.get(params.id)
      render bookInstance as JSON
    }else{
      render Book.list() as JSON
    }
}

However, since there is no JSON to parse I'm getting the following exception:

2011-06-07 09:45:20,373 [http-8080-1] ERROR converters.JSONParsingParameterCreationListener  - Error parsing incoming JSON request: Error parsing JSON
org.codehaus.groovy.grails.web.converters.exceptions.ConverterException: Error parsing JSON
    at grails.converters.JSON.parse(JSON.java:289)
    at grails.converters.JSON.parse(JSON.java:311)
    at grails.converters.JSON.parse(JSON.java:334)
    at grails.converters.JSON$parse.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:124)
    at org.codehaus.groovy.grails.web.converters.JSONParsingParameterCreationListener.paramsCreated(JSONParsingParameterCreationListener.groovy:42)
    at org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest.informParameterCreationListeners(GrailsWebRequest.java:171)
    at org.codehaus.groovy.grails.web.mapping.filter.UrlMappingsFilter.doFilterInternal(UrlMappingsFilter.java:181)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter.obtainContent(GrailsPageFilter.java:245)
    at org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter.doFilter(GrailsPageFilter.java:134)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.codehaus.groovy.grails.web.servlet.filter.GrailsReloadServletFilter.doFilterInternal(GrailsReloadServletFilter.java:104)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:69)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.codehaus.groovy.grails.web.filters.Hidden开发者_JAVA百科HttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:69)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
    at java.lang.Thread.run(Thread.java:680)
Caused by: org.codehaus.groovy.grails.web.json.JSONException: Missing value. at character 0 of 
    at org.codehaus.groovy.grails.web.json.JSONTokener.syntaxError(JSONTokener.java:473)
    at org.codehaus.groovy.grails.web.json.JSONTokener.nextValue(JSONTokener.java:358)
    at grails.converters.JSON.parse(JSON.java:280)
    ... 44 more

Is this a bug or is there someway to tell Grails that if no JSON exists, just don't try and parse anything?


However, since there is no JSON to parse I'm getting the following exception:

I'm not sure why there's no JSON to parse. If Book.list() returns an empty List when there are no books, this should be converted to an empty (JavaScript) array. You can verify this by running the following code in the Grails console

import grails.converters.*

String json = [] as JSON
assert json == '[]'

If Book.list() returns null, then you can easily replace it with an empty list by changing

render Book.list() as JSON

to

// If you like micro-optimizations, replace [] with Collections.emptyList()
def allBooks = Book.list() ?: []
render allBooks as JSON
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜