Closed GoogleCodeExporter closed 8 years ago
I don't know the purpose of current ConverterUtils.jsonToMap() implementation,
however I've seen that in order to extract a map with the request parameters
the following would be enough for me.
static Map jsonToMap(InputStream input, String encoding) {
def slurper = new groovy.json.JsonSlurper()
return slurper.parse(new InputStreamReader (input, encoding));
// original implementation
// def adapter = new RequestStreamAdapter(input)
// adapter.characterEncoding = encoding
// adapter.setAttribute(GrailsApplicationAttributes.CONTENT_FORMAT, 'json')
//
// def params = new GrailsParameterMap(adapter)
// jsonListener.paramsCreated(params)
// params.iterator().next().value
}
Original comment by davide.cavestro
on 22 Jun 2012 at 1:06
Hi Davide,
The purpose of the current jsonToMap()/xmlToMap() implementation is to reuse
how Grails binds JSON/XML to domain objects. This is done via
-
https://github.com/grails/grails-core/blob/v2.0.4/grails-plugin-converters/src/m
ain/groovy/org/codehaus/groovy/grails/web/converters/JSONParsingParameterCreatio
nListener.groovy and
-
https://github.com/grails/grails-core/blob/v2.0.4/grails-plugin-converters/src/m
ain/groovy/org/codehaus/groovy/grails/web/converters/XMLParsingParameterCreation
Listener.groovy
and used in ConverterUtils of grails-jaxrs
https://github.com/krasserm/grails-jaxrs/blob/jaxrs-0.6/src/groovy/org/grails/ja
xrs/support/ConverterUtils.groovy#L45
Although I can confirm that your alternative proposal works for the existing
JUnit tests, I can also see that the Grails built-in mechanism is doing more
than your proposed solution (e.g. flatten keys and so on ...). So, I'm hesitant
to implement a proprietary mechanism for JSON/XML to domain object conversion.
This however doesn't solve the Servlet 2.5/3.0 problem. I hope to find some
time during the next days to provide a fix. Should you have further proposals
how to address this issue, I'd highly appreciate.
Thanks,
Martin
Original comment by krass...@googlemail.com
on 25 Jun 2012 at 6:31
Hi Martin,
I wasn't aware at all about the purpose of ParsingParameterCreationListener.
I'll take a look. The root of the problem seems the usage of mock request...
btw
http://grails.1312388.n4.nabble.com/Support-Servlet-3-0-and-2-5-in-the-same-plug
in-td4498930.html could give some useful ideas.
Cheers
Davide
Original comment by davide.cavestro
on 25 Jun 2012 at 8:01
Somewhat following Burt's advice I've tried an hybrid approach: proxying the
MockHttpServletRequest instance instead of obtaining it trough inheritance.
This way we should avoid hard dependencies on servlet api 3.0 and still be able
to use springs' mock implementation of HttpServletRequest.
Something like
static Map jsonToMap(InputStream input, String encoding) {
// def adapter = new RequestStreamAdapter(input)
// adapter.characterEncoding = encoding
// adapter.setAttribute(GrailsApplicationAttributes.CONTENT_FORMAT,
'json')
def adapter = newRequestStreamAdapter(input, encoding, 'json')
def params = new GrailsParameterMap(adapter)
jsonListener.paramsCreated(params)
params.iterator().next().value
}
where newRequestStreamAdapter is implemented as follows
static def newRequestStreamAdapter (InputStream stream, String characterEncoding, String format) {
final MockHttpServletRequest req = new MockHttpServletRequest ();
req.characterEncoding = characterEncoding
req.setAttribute(GrailsApplicationAttributes.CONTENT_FORMAT, format)
return (HttpServletRequest)Proxy.newProxyInstance(HttpServletRequest.class.getClassLoader(),
[HttpServletRequest.class] as Class[], new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) {
String methodName = method.getName();
if ("getFormat".equals(methodName)) {
return req.getAttribute(GrailsApplicationAttributes.CONTENT_FORMAT);
}
if ("getInputStream".equals(methodName)) {
if (stream instanceof ServletInputStream) {
return stream
} else if (stream) {
return new DelegatingServletInputStream(stream)
} else {
return req.getInputStream()
}
}
return req.getClass().getMethod(
method.getName(), method.getParameterTypes()).invoke(req, args);
}
});
}
Of course the same apply to xml requests.
PS: it should still be adapted with the addition of ad-hoc management for
servlet 3.0 new methods, such as "getParts" and so on... something like
if ("startAsync".equals(methodName)) {
throw new UnsupportedOperationException();
}
that would be the counterpart of actual RequestStreamAdapter implementation.
I'm going to patch the jaxrs plugin locally and give it a try.
Cheers
Davide
Original comment by davide.cavestro
on 25 Jun 2012 at 1:18
Great, please create a pull request if it works. Thanks for your feedback, help
and contributions. Cheers, Martin
Original comment by krass...@googlemail.com
on 25 Jun 2012 at 2:27
Just merged you pull request to master. Thanks for awesome work!
Original comment by krass...@googlemail.com
on 9 Jul 2012 at 10:56
I use tomcat 6, java version "1.6.0_24" and tried the version with this fix
from git,
but I get following error:
Stacktrace follows:
org.codehaus.groovy.grails.web.servlet.mvc.exceptions.ControllerExecutionExcepti
on: Executing action [handle] of controller [org.grails.jaxrs.JaxrsController]
in plugin [jaxrs] caused exception: Runtime error executing action
at org.grails.jaxrs.web.JaxrsFilter.doFilterInternal(JaxrsFilter.java:46)
at com.googlecode.psiprobe.Tomcat60AgentValve.invoke(Tomcat60AgentValve.java:30)
at java.lang.Thread.run(Thread.java:679)
Caused by:
org.codehaus.groovy.grails.web.servlet.mvc.exceptions.ControllerExecutionExcepti
on: Runtime error executing action
... 3 more
Caused by: java.lang.reflect.InvocationTargetException
... 3 more
Caused by: java.lang.NoClassDefFoundError:
org.codehaus.groovy.grails.plugins.testing.GrailsMockHttpServletRequest
at org.grails.jaxrs.support.ConverterUtils.newRequestStreamAdapter(ConverterUtils.groovy:152)
at org.grails.jaxrs.support.ConverterUtils.jsonToMap(ConverterUtils.groovy:101)
at org.grails.jaxrs.provider.JSONReader.readFrom(JSONReader.java:88)
at org.grails.jaxrs.provider.JSONReader.readFrom(JSONReader.java:61)
at org.grails.jaxrs.support.MessageBodyReaderSupport.readFrom(MessageBodyReaderSupport.java:55)
at com.sun.jersey.spi.container.ContainerRequest.getEntity(ContainerRequest.java:474)
at com.sun.jersey.server.impl.model.method.dispatch.EntityParamDispatchProvider$EntityInjectable.getValue(EntityParamDispatchProvider.java:123)
at com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:46)
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:153)
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:203)
at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
at com.sun.jersey.server.impl.uri.rules.SubLocatorRule.accept(SubLocatorRule.java:134)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1483)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1414)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1363)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1353)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:414)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:708)
at org.grails.jaxrs.web.JaxrsContext$JaxrsServiceImpl.process(JaxrsContext.java:192)
at org.grails.jaxrs.JaxrsController$_closure1.doCall(JaxrsController.groovy:48)
thanks for your help,
cahya.
Original comment by cahya.wi...@gmail.com
on 26 Jul 2012 at 8:59
Hi cahya,
the plugin should still have a compile-time dependency on spring test (as
per
https://github.com/krasserm/grails-jaxrs/blob/master/grails-app/conf/BuildConfig
.groovy#L45
and http://code.google.com/p/grails-jaxrs/issues/detail?id=39)... I just
wonder how that library could have been excluded from your runtime
classpath: did you explicitly excluded it? If so removing the exclusion
should do the trick...
Original comment by davide.cavestro
on 30 Jul 2012 at 8:40
@cahya
Sorry, I was wrong on my previous comment... I introduced a dependency on
GrailsMockHttpServletRequest from grails-test. That's normally available only
at test time. I'm going to see if it can be replaced with
org.springframework.mock.web.MockHttpServletRequest (for which applies what I
said on my previous post). IN the meantime you could add a compile or runtime
dependency on grails-test.
Cheers
Davide
Original comment by davide.cavestro
on 1 Aug 2012 at 7:32
@cahya
could you please check the further fix I merged into master branch yesterday?
It works for me both with run-app and deploying the war for a servlet 2.5
grails 2.0.4 app on tomcat 6 and 7.
Original comment by davide.cavestro
on 2 Aug 2012 at 7:10
I have tried it and it works now on tomcat6 without any problem.
Thanks
Original comment by cahya.wi...@gmail.com
on 6 Aug 2012 at 5:21
Is there a plan to do a release with this fix incorporated?
Original comment by m...@tristanburch.com
on 7 Jan 2013 at 10:51
I've published a binary for release 0.7 at
http://code.google.com/p/grails-jaxrs/downloads/detail?name=grails-jaxrs-0.7.zip
&can=2&q=
could you please give it a try downloading the zip and installing from
filesystem?
Cheers
Davide
Original comment by davide.cavestro
on 9 Jan 2013 at 5:31
Thanks for providing 0.7. It, and Burt's advice on the dependency issue,
solved the ClassNotFoundException for javax.servlet.http.Part when submitting
XML with Tomcat 6 and grails 2.1.1. (It only occurred in production on
Tomcat6, not in development in GGTS).
I downloaded and installed it from the filesystem. When will it be available
through the normal 'install-plugin' mechanism?
Original comment by wis...@gmail.com
on 17 Jan 2013 at 5:47
We'll upload it to the central repo soon. When done we'll post a message on the
grails-jaxrs-discuss mailing list.
Original comment by krass...@googlemail.com
on 18 Jan 2013 at 7:28
Hi,
when will the new version 0.7 being available?
The workaround in the above download link failed?
Can you fix it soon, please?
Cheers
Hardy
Original comment by Hardy....@gmail.com
on 20 Mar 2013 at 10:14
Original issue reported on code.google.com by
davide.cavestro
on 22 Jun 2012 at 8:10