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
精彩评论