Setup
Create a directory called jsonlist. The following is the contents of my roo.log.
// Spring Roo 1.1.1.RELEASE [rev 156ccd6]Create a basic html page (I called mine testJSONPrototype.html) to test the JavaScript access.
project --topLevelPackage ca.digitalface.jsonlist
persistence setup --database HYPERSONIC_IN_MEMORY --provider HIBERNATE
entity --class ~.Item --testAutomatically
field string --fieldName name --notNull
controller all --package ~.web
json all
Put it in src/main/webapp.
<html>Download the prototype.js file from www.prototypejs.org and put it in src/main/webapp.
<head>
<title>Accessing ROO with JSON and Prototype.js</title>
<script type="text/javascript" src="./prototype.js"></script>
<script type="text/javascript">
document.observe('dom:loaded', function() {
var url = 'http://localhost:8080/jsonlist/items';
new Ajax.Request(url, {
method: 'POST',method: 'GET',
contentType: 'application/json',
requestHeaders: ["Accept","application/json"],
onLoaded: function(){alert("sent");},
onSuccess: function(transport) {
var val = transport.responseText;
var target = $('target');
if (transport != null)
target.update('Response: '+val);
else
target.update('Transport is null!');
}
});
});
</script>
</head>
<body>
<h1>Accessing ROO with JSON and Prototype.js</h1>
<div id="target">List of Items.</div>
</body>
</html>
Execute
Run the application with mvn tomcat:run and then open http://localhost:8080/jsonlist in your browser.
Add some items to the list.
Here's where the confusion comes in.
If you use curl at the command line, you get the JSON text as you would expect,
curl -i -H "Accept: application/json" http://localhost:8080/jsonlist/itemshowever if you go to the test page (localhost:8080/jsonlist/testJSONPrototype.html) we created above it fails with the following error and stack trace.
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: application/json;charset=UTF-8
Content-Length: 92
Date: Mon, 24 Jan 2011 12:57:32 GMT
[{"id":1,"name":"aaaaaaaaaaa","version":0},{"id":2,"name":"bbbbbbbbbbbbbbbbbb","version":0}]
Stepping back two steps is not supportedHere are the headers that were captured by the "Live HTTP Headers" plugin for Firefox.
flexjson.JSONTokener.back(JSONTokener.java:83)
flexjson.JSONTokener.nextValue(JSONTokener.java:378)
flexjson.JSONDeserializer.deserialize(JSONDeserializer.java:150)
ca.digitalface.jsonlist.Item_Roo_Json.fromJsonToItem_aroundBody0(Item_Roo_Json.aj:21)
ca.digitalface.jsonlist.Item_Roo_Json.ajc$interMethod$ca_digitalface_jsonlist_Item_Roo_Json$ca_digitalface_jsonlist_Item$fromJsonToItem(Item_Roo_Json.aj:1)
ca.digitalface.jsonlist.Item.fromJsonToItem(Item.java:1)
ca.digitalface.jsonlist.Item_Roo_Json.ajc$interMethodDispatch1$ca_digitalface_jsonlist_Item_Roo_Json$ca_digitalface_jsonlist_Item$fromJsonToItem(Item_Roo_Json.aj)
ca.digitalface.jsonlist.web.ItemController_Roo_Controller.ajc$interMethod$ca_digitalface_jsonlist_web_ItemController_Roo_Controller$ca_digitalface_jsonlist_web_ItemController$createFromJson(ItemController_Roo_Controller.aj:107)
ca.digitalface.jsonlist.web.ItemController.createFromJson(ItemController.java:1)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:113)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
java.lang.Thread.run(Thread.java:662)
http://localhost:8080/jsonlist/itemsI have not yet figured out the solution to this, but I thought I'd open a JIRA Ticket and see what comes of it. Watch this space for updates.
POST /jsonlist/items HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.04 (lucid) Firefox/3.6.13
Accept: application/json
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
X-Requested-With: XMLHttpRequest
X-Prototype-Version: 1.7
Content-Type: application/json; charset=UTF-8
Referer: http://localhost:8080/jsonlist/testJSONPrototype.html
Content-Length: 0
Cookie: JSESSIONID=2F82F1236EA5EFDC0C0464A87F64EB67
Pragma: no-cache
Cache-Control: no-cache
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=1BE83EB4104405124F75B91A652197D5; Path=/jsonlist
Content-Type: text/html;charset=UTF-8
Content-Language: en-US
Content-Length: 7304
Date: Mon, 24 Jan 2011 14:21:51 GMT
Update
Well, thanks to Stefan's comment the solution was easy. 8^)
I only had to change the method from POST to GET, and everything went as planned. I was sure that I had tried that, but I guess not.
There is no denying the value of a second set of eyes!
So to understand the intention of your test application - you want to send a HTTP POST message to the JSON enabled controller? If so you should make sure that you actually send the JSON document along in the POST message. Currently you are not sending any data which is visible from your headers: Content-Length: 0
ReplyDeleteI would suggest you start off by doing a HTTP GET first to retrieve and display JSON data coming from your controller.
-Stefan