`

Neo4j: Get Json Parameters in Extentions with Spring Data Neo4j

 
阅读更多

I want to write a extention to provide REST API for client to add a new user to Neo4j database, which I also use Spring Data Neo4j to OGM.  Client just sends a josn post to the extention, and just get a simple status result.

 

1. Create a maven project in eclipse  with  pom.xml  to manage related dependencies

 

2. Create Modle

package com.fadeinfadeout.modle;

import java.util.HashSet;
import java.util.Set;

import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.neo4j.graphdb.Direction;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.Indexed;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.RelatedTo;


 
@NodeEntity
@XmlRootElement
@JsonAutoDetect
public class User {
    private String name;

    @Indexed(unique = true)
    private String userId;

    private String phoneNumber;

    @GraphId
    private Long nodeId;
    
    @RelatedTo(type = "IS_FRIEND_OF", direction = Direction.BOTH)
    private Set<User> friends;

    public User() {
 
    }

    public User(String userId, String name, String phoneNumber) {
	this.userId = userId;
	this.name = name;
	this.phoneNumber = phoneNumber;
    }

    public Long getNodeId() {
        return nodeId;
    }

    public void setNodeId(Long nodeId) {
        this.nodeId = nodeId;
    }

    public String getName() {
	return name;
    }

    public void setName(String name) {
	this.name = name;
    }

    public String getUserId() {
	return userId;
    }

    public void setUserId(String userId) {
	this.userId = userId;
    }

    public String getPhoneNumber() {
	return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
	this.phoneNumber = phoneNumber;
    }

    public Set<User> getFriends() {
	return friends;
    }

    public void setFriends(Set<User> friends) {
	this.friends = friends;
    }

    public void addFriends(User friend) {
	if (friends == null)
	    friends = new HashSet<User>();

	friends.add(friend);
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        User user = (User) o;

        if (nodeId != null ? !nodeId.equals(user.nodeId) : user.nodeId != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return nodeId != null ? nodeId.hashCode() : 0;
    }
    
    public String toString(){
	return "userId="+this.userId +"\tname="+this.name+"\tpN="+this.phoneNumber;
    }

}

 

In order to using auto json wired in jersey(which is a Restful framework embeded in Neo4j to provide Remote access), you should anotate the mode class with

@XmlRootElement
@JsonAutoDetect

 

and  add dependencies in pom.xml

<dependency>
		<groupId>com.sun.jersey</groupId>
		<artifactId>jersey-json</artifactId>
		<version>1.9</version>
		<exclusions>
			<exclusion>
				<artifactId>jackson-core-asl</artifactId>
				<groupId>org.codehaus.jackson</groupId>
			</exclusion>
			<exclusion>
				<artifactId>jackson-jaxrs</artifactId>
				<groupId>org.codehaus.jackson</groupId>
			</exclusion>
			<exclusion>
				<artifactId>jersey-core</artifactId>
				<groupId>com.sun.jersey</groupId>
			</exclusion>
		</exclusions>
</dependency>

 

3. Create a spring data neo4j  repository to operate  User

package com.fadeinfadeout.repository;

import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.GraphRepository;

import com.fadeinfadeout.modle.User;

public interface UserRepository extends GraphRepository<User> {

    @Query(value = 
	    "match (n)-[r:IS_FRIEND_OF]-(friend)-[r2:IS_FRIEND_OF]-(fof) " +
		    "where n.userId) = {0} " + 
		    "return distinct fof")
    Iterable<User> getFriendsOfFriends(String userId);
}

 

4. Inorder to use SDN in Neo4j unmanaged extentions, We should inite SDN with SpringPluginInitializer

package com.fadeinfadeout.plugins;

import java.util.Collection;
import java.util.logging.Logger;

import org.apache.commons.configuration.Configuration;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.server.plugins.Injectable;
import org.springframework.data.neo4j.server.SpringPluginInitializer;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.util.Assert;

import com.fadeinfadeout.repository.UserRepository;

public class FadeinFadeoutNeo4jPluginInitializer extends SpringPluginInitializer{
    private static final Logger logger = Logger.getLogger(FadeinFadeoutNeo4jPluginInitializer.class.getName());

    @SuppressWarnings("unchecked")
    public FadeinFadeoutNeo4jPluginInitializer() {
	super(new String[] { "META-INF/spring/application-context.xml" },
		expose("neo4jTemplate", Neo4jTemplate.class), 
		expose("userRepository", UserRepository.class));
   }
    
}

 

This  class is aimed to initialize  SDN and expose  Beans which could be used in extentions

The  full-qualified class name should be placed in file org.neo4j.server.plugins.PluginLifecycle  which located at

src/main/resources/MATA-INF/services dir.     When start neo4j server,  neo4j will pick the file and scan its contnets, then initialize related classes.

 

 

5.Create a Unmanaged Extentions to provide clients User operation API

 

package com.fadeinfadeout.unmanagedext;

import java.util.logging.Logger;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import com.fadeinfadeout.modle.User;
import com.fadeinfadeout.plugins.FadeinFadeoutNeo4jPluginInitializer;
import com.fadeinfadeout.repository.UserRepository;

@Path("/user")
public class UserCtrollerUnmanagedExt {
    private static final String ERROR_MSG = "{Result:[error]}";
    private static final String OK_MSG = "{Result:[OK]}";
    private static final Logger logger = Logger.getLogger(UserCtrollerUnmanagedExt.class.getName());

    @Context
    private UserRepository userRepo;

    @Path("/addUser")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response addUser(User user) {
	String userId = null;
	String name = null;
	String phoneNumber = null;

	userId = user.getUserId();
	name = user.getName();
	phoneNumber = user.getPhoneNumber();

	logger.info("Json user paramerters : " + user.toString());
	
	if (userId == null || name == null || phoneNumber == null) {
	    return Response.status(Status.NOT_ACCEPTABLE).entity(ERROR_MSG).build();
	}
	// User newUser = new User(userId, name, phoneNumber);
	 userRepo.saveOnly(user);

	return Response.status(Status.OK).entity(OK_MSG).build();
    }

}

 

To let neo4j knows the extention, you should configure it in  conf/neo4j-server.properties

 

org.neo4j.server.thirdparty_jaxrs_classes=com.fadeinfadeout=/fifo

 

Your client can use the following path to access the extention

 

curl -i -H 'content-type: application/json' -X POST 
-d '{"userId":"1","name":"zhaohj","phoneNumber":"18190752251"}'
 htt:7474/fifo/user/addUser

 

 

6. Integrate SDN in Neo4j, you should  configure dependencies in pom.xml. the following sinppets are some important dependencies

 

<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-neo4j-aspects</artifactId>
	<version>${neo4j.springdata.version}</version>
	<exclusions>
		<exclusion>
			<groupId>org.neo4j</groupId>
			<artifactId>neo4j-kernel</artifactId>
		</exclusion>
		<exclusion>
			<groupId>org.neo4j</groupId>
			<artifactId>neo4j</artifactId>
		</exclusion>
		<exclusion>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
		</exclusion>
		<exclusion>
			<groupId>org.aspectj</groupId>
			<artifactId>*</artifactId>
		</exclusion>

		<exclusion>
			<artifactId>geronimo-jta_1.1_spec</artifactId>
			<groupId>org.apache.geronimo.specs</groupId>
		</exclusion>
	</exclusions>
</dependency>

 

Note: 

A:Due to transitive dependices, some jars are provided by Neo4j in  lib and system/lib dir. So, you should exclude these jars from pom.xml

 

B:Because many spring jars include some meta data file in META-INF/ dir, when you build the final jar, you should merge these meta file using  maven shade plugin, otherwise some schema Handler can't found when start neo4j server

 

<build>
 <pluginManagement>
  <plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-shade-plugin</artifactId>
	<version>2.3</version>
	<executions>
		<execution>
		<phase>package</phase>
		<goals>
			<goal>shade</goal>
	        </goals>
		<configuration>
		      <transformers>
				<transformer
					implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
					<resource>META-INF/spring.handlers</resource>
				</transformer>
				<transformer
					implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
					<resource>META-INF/spring.schemas</resource>
				</transformer>
				<transformer
					implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
					<resource>META-INF/spring.tooling</resource>
				</transformer>
				<transformer
					implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
					<resource>META-INF/spring.factories</resource>
				</transformer>
				<transformer
					implementation="org.apache.maven.plugins.shade.resource.ComponentsXmlResourceTransformer" />
				<transformer
					implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
			</transformers>
		</configuration>
	</execution>
      </executions>
     </plugin>

    </plugins>
   </pluginManagement>
   <plugins>
      <plugin>
	<groupId>org.apache.maven.plugins</groupId>
		<artifactId>maven-shade-plugin</artifactId>
      </plugin>
   </plugins>
</build>

 

 

The configure SDN, you should put the SDN configuration file application-context.conf in     src/main/resoureces/MATA-INF/spring

 

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx.xsd
            http://www.springframework.org/schema/data/neo4j
            http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd">


	<context:annotation-config />
	<context:spring-configured />
	<context:component-scan base-package="com.fadeinfadeout">
	</context:component-scan>
	<neo4j:config id="graphDatabaseService"
		storeDirectory="/home/zhaohj/hadoop/neo4j-community-2.1.7/data/graph.db"
		base-package="com.fadeinfadeout.modle" graphDatabaseService="graphDatabaseService" />

	<!-- Instructs Spring Data where to look for repository implementations -->
	<neo4j:repositories base-package="com.fadeinfadeout.repository" />
	<tx:annotation-driven mode="aspectj" />

</beans>

 

The final project dirs likes



 

 

 

 

 

References

https://jersey.java.net/documentation/1.9/json.html

https://inserpio.wordpress.com/2014/04/30/extending-the-neo4j-server-with-spring-data-neo4j/

http://neo4j.com/docs/stable/server-unmanaged-extensions.html

https://github.com/AtomRain/neo4j-extensions

http://docs.spring.io/spring-data/neo4j/docs/3.0.0.RELEASE/reference/html/reference_neo4j-server.html

http://examples.javacodegeeks.com/enterprise-java/rest/jersey/json-example-with-jersey-jackson/

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 大小: 51.4 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics