Serializing node to json

1,561 views
Skip to first unread message

Samwillie

unread,
Apr 27, 2012, 3:58:55 AM4/27/12
to Neo4j
Hi,

I use spring mvc rest to serialize a node into json/xml. However I
always keep getting the exception:

"The resource identified by this request is only capable of generating
responses with characteristics not acceptable according to the request
"accept" headers ()."

I would appreciate some information or examples that point to
converting node and node list to json/xml.

many thanks,

Peter Neubauer

unread,
Apr 27, 2012, 4:03:46 AM4/27/12
to ne...@googlegroups.com
Hi there,
if you look at the docs,
http://docs.neo4j.org/chunked/snapshot/rest-api-service-root.html, are
you sure you have the exact headers that are listed there?

Content-Type:application/json
accept:application/json

Cheers,

/peter neubauer

G:  neubauer.peter
S:  peter.neubauer
P:  +46 704 106975
L:   http://www.linkedin.com/in/neubauer
T:   @peterneubauer

If you can write, you can code - @coderdojomalmo
If you can sketch, you can use a graph database - @neo4j

Samwillie

unread,
Apr 27, 2012, 4:35:57 AM4/27/12
to Neo4j
Hi Peter,

Yes, I have the headers declared - attached inline example. I use
Spring MVC 3 Rest framework for serialization to XML and JSON - it
works for objects but not on nodes.

@RequestMapping(value = "/node/{id}", method = RequestMethod.GET,
headers = "Accept=application/xml, application/json")
@ResponseBody
public Node getExampleNode(@PathVariable Long id) {
Node exampleNode = service.getNodeById(id);
return exampleNode;
}

The converters are defined in spring config file:

<bean id="jsonMessageConverter"

class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json"/
>
</bean>
<bean id="xmlMessageConverter"

class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<constructor-arg ref="jaxbMarshaller"/>
<property name="supportedMediaTypes" value="application/xml"/>
</bean>

Is this the correct configuration?

Greets,

On Apr 27, 10:03 am, Peter Neubauer <peter.neuba...@neotechnology.com>
wrote:
> Hi there,
> if you look at the docs,http://docs.neo4j.org/chunked/snapshot/rest-api-service-root.html, are

Michael Hunger

unread,
Apr 27, 2012, 4:50:24 AM4/27/12
to ne...@googlegroups.com
I had the same issue yesterday.

A neo4j node is not a POJO but a wrapper to internal infrastructure of neo4j.

You should write a converter that takes a node and converts it into a format that you can use for that use-case (either just properties or with id or with relationships)

What are you trying to achieve? Add a REST API to an embedded database? Or is it an exercise?

Otherwise you can look into using a WrappingNeoServerBootstrapper for adding the REST API and Webadmin to an embedded DB.


Michael

Samwillie

unread,
Apr 27, 2012, 5:02:13 AM4/27/12
to Neo4j
Hi Michael,

Thanks. Yes this is what I am trying to do - create an embedded
database (values migrated from mysql) and then create a rest API
interface (spring mvc 3 rest) to access the nodes (CRUD) for the nodes
in the graph database.

This means that I need to write a converter for each node and list of
nodes - a converter to convert to POJO that can be used by spring to
serialize to json, right?
Micahel, do you have an example converter or point me to one?

Also, should the WrappingNeoServerBootstrapper be in the same web
application, that can be triggered by a REST method call?

Many thanks...

On Apr 27, 10:50 am, Michael Hunger <michael.hun...@neotechnology.com>
wrote:

Michael Hunger

unread,
Apr 27, 2012, 5:35:56 AM4/27/12
to ne...@googlegroups.com
It is actually quite simple.

you can take the code as inspiration that runs console.neo4j.org

https://github.com/neo4j-contrib/rabbithole/blob/master/src/main/java/org/neo4j/community/console/Neo4jService.java

you mainly need:

Map<String, Object> toMap(PropertyContainer pc) {
Map<String, Object> result = new TreeMap<String, Object>();
for (String prop : pc.getPropertyKeys()) {
result.put(prop, pc.getProperty(prop));
}
return result;
}

for relationships:

Map<String, Object> data = toMap(rel);
data.put("id", rel.getId());
data.put("source", nodeIndex.indexOf(rel.getStartNode().getId()));
data.put("target", nodeIndex.indexOf(rel.getEndNode().getId()));
data.put("type", rel.getType().name());

for nodes:
Map<String, Object> data = toMap(n);
data.put("id", n.getId());

and then return that map (or list of maps to spring)

best is to have a _convert_ method which takes an object, makes instanceof-checks of node, relationship, path, executionresult, and iterable and then calls convert several times for the different types

If you want to stream the json you can also use jacksons JsonGenerator as in here:
https://github.com/neo4j-contrib/streaming-cypher
https://github.com/neo4j-contrib/streaming-cypher/blob/master/src/main/java/org/neo4j/server/extension/streaming/cypher/json/JsonResultWriters.java

Cheers

Michael

Samwillie

unread,
May 2, 2012, 12:20:44 AM5/2/12
to Neo4j
Hi Michael,

Many thanks for your time and reply. I now have the map with node and
its properties ready to be returned to Spring. With the message
converters in the spring configuration file, mentioned in an earlier
reply in this thread, it does not automatically convert the map to XML
and JSON. Is there some special setup required?

Thanks again for your time,

Greets

On Apr 27, 11:35 am, Michael Hunger <michael.hun...@neotechnology.com>
wrote:
> It is actually quite simple.
>
> you can take the code as inspiration that runs console.neo4j.org
>
> https://github.com/neo4j-contrib/rabbithole/blob/master/src/main/java...
>
> you mainly need:
>
>     Map<String, Object> toMap(PropertyContainer pc) {
>         Map<String, Object> result = new TreeMap<String, Object>();
>         for (String prop : pc.getPropertyKeys()) {
>             result.put(prop, pc.getProperty(prop));
>         }
>         return result;
>     }
>
> for relationships:
>
>             Map<String, Object> data = toMap(rel);
>             data.put("id", rel.getId());
>             data.put("source", nodeIndex.indexOf(rel.getStartNode().getId()));
>             data.put("target", nodeIndex.indexOf(rel.getEndNode().getId()));
>             data.put("type", rel.getType().name());
>
> for nodes:
>         Map<String, Object> data = toMap(n);
>         data.put("id", n.getId());
>
> and then return that map (or list of maps to spring)
>
> best is to have a _convert_ method which takes an object, makes instanceof-checks of node, relationship, path, executionresult, and iterable and then calls convert several times for the different types
>
> If you want to stream the json you can also use jacksons JsonGenerator as in here:https://github.com/neo4j-contrib/streaming-cypherhttps://github.com/neo4j-contrib/streaming-cypher/blob/master/src/mai...

Michael Hunger

unread,
May 2, 2012, 1:47:05 AM5/2/12
to ne...@googlegroups.com
Did you use @ResponseBody ?

Sent from mobile device

Samwillie

unread,
May 2, 2012, 3:46:49 AM5/2/12
to Neo4j
Hi Michael,

Yes I do, here is an example:

@RequestMapping(value = "/node/{id}", method = RequestMethod.GET,
headers = "Accept=application/xml, application/json")
@ResponseBody
public Entity getEntity(@PathVariable Long id) {
Node entityNode = neoService.getEntityById(id);
return entityNode;
}

This is one of my controller methods. The 'Entity' here is a domain
object that reflects a table (used by hibernate) and annotated by
@XmlRootElement tag, that marshals to XML fine with Spring. However,
when I return the same entity as a Neo4j "node" it does not get
converted automatically back to XML or JSon. Based on your earlier
reply I converted the node to a map as follows:

Map<String, Object> result =
objectSerializer.getMapForNode(entityNode);

At this point, I get all the node and its properties in the map -
thanks to your inputs.

Now I need to return this map somehow to Spring to render it into XML
and JSON. The configuration of both converters are as posted in my
earlier reply in this thread.

Please let me know if you require any further information.

Greets,



On May 2, 7:47 am, Michael Hunger <michael.hun...@neopersistence.com>
wrote:
> Did you use @ResponseBody ?
>
> Sent from mobile device
>
> >> If you want to stream the json you can also use jacksons JsonGenerator as in here:https://github.com/neo4j-contrib/streaming-cypherhttps://github.com/n......

Michael Hunger

unread,
May 2, 2012, 5:54:29 AM5/2/12
to ne...@googlegroups.com
But didn't you say you create the maps and return those? Unfortunately I don't have too much experience with Spring MVC.

You could also create a jaxb-converter for Nodes and Relationships and register it then the Node/Relationship would be rendered automatically.

Perhaps we should provide one for Nodes, Relationships and Paths in Neo4j itself. Could you raise an issue on that at http://github.com/neo4j/community/issues ?
Reply all
Reply to author
Forward
0 new messages