Jax-RS (JSR 311) is a Java API for developing applications using the REST architecture.
Assume that you want to create a demo REST service using Jax-RS that requires the followings:
This REST service shows a list of usernames.
To run this REST service, you should belong to a defined group.
The list of usernames will be under the JSON responses format.
Create a Maven project named rest with the following structure:
Declare the dependencies needed for the demo REST service in the pom.xml
of the Java project
(you can go to the eXo Platform repository to check the artifact versions).
exo.ws.rest.core: Used for REST service.
jsr250-api: Used for annotation.
json-rpc: Used for JSON.
exo.core.component.organization.api: Used for retrieving data.
The pom.xml
file now looks like:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>exo.rest.service</groupId>
<artifactId>rest</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>maven</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.exoplatform.ws</groupId>
<artifactId>exo.ws.rest.core</artifactId>
<version>2.3.7-GA</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.exoplatform.core</groupId>
<artifactId>exo.core.component.organization.api</artifactId>
<version>2.6.0-GA</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.metaparadigm</groupId>
<artifactId>json-rpc</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Edit the java/exo/rest/service/RestUserService.java
file.
package exo.rest.service;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.annotation.security.RolesAllowed;
import org.exoplatform.commons.utils.ListAccess;
import org.exoplatform.container.ExoContainer;
import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.services.organization.OrganizationService;
import org.exoplatform.services.organization.User;
import org.exoplatform.services.organization.UserHandler;
import org.exoplatform.services.rest.resource.ResourceContainer;
import org.exoplatform.services.security.Identity;
import org.exoplatform.services.security.IdentityRegistry;
import org.json.JSONArray;
import org.json.JSONObject;
/**
* Rest User Service!
*/
@Path("/demo")
@Produces("application/json")
public class RestUserService implements ResourceContainer {
@GET
@Path("/hello/{name}")
@RolesAllowed({"administrators"})
public String hello(@PathParam("name")
String name) {
return "Hello " + name;
}
@GET
@Path("/listusers/{offet}")
public Response getListUserName(@Context SecurityContext sc,@PathParam("offet") Integer offset) {
JSONArray list = new JSONArray();
JSONObject jsonObject = new JSONObject();
String groupToCheck = "/platform/administrators";
CacheControl cacheControl = new CacheControl(); cacheControl.setNoCache(true);
cacheControl.setNoStore(true);
if (sc.getUserPrincipal() == null || !this.isMemberOf(sc.getUserPrincipal().getName(), groupToCheck)) {
jsonObject.put("rights","NOT-ALLOWED");
list.put(jsonObject);
} else {
OrganizationService organizationService = (OrganizationService) ExoContainerContext.getCurrentContainer()
.getComponentInstanceOfType(OrganizationService.class);
UserHandler userHandler = organizationService.getUserHandler();
try {
ListAccess<User> allUsers = userHandler.findAllUsers();
if(offset == null || offset < 0)
offset = 0;
int limit = 1000;
int total = limit + offset;
int totalUsers = allUsers.getSize();
if(offset < totalUsers && total > totalUsers){
total = totalUsers;
}
User[] users = null;
for (int i = offset; i < total; i++) {
users = allUsers.load(i,1);
jsonObject = new JSONObject();
jsonObject.put("username", users[0].getUserName());
list.put(jsonObject);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return Response.ok(list.toString(), MediaType.APPLICATION_JSON).cacheControl(cacheControl).build();
}
private boolean isMemberOf(String username, String role) {
ExoContainer container = ExoContainerContext.getCurrentContainer();
IdentityRegistry identityRegistry = (IdentityRegistry) container.getComponentInstanceOfType(IdentityRegistry.class);
Identity identity = identityRegistry.getIdentity(username);
return identity.isMemberOf(role);
}
}
In the above code, ResourceContainer needs to be implemented. This is used to make eXo services (for example, the components deployed inside eXo Container) simply and transparently accessible via HTTP in a RESTful manner. In other words, these services should be viewed as a set of REST Resources-endpoints of the HTTP request-response chain. Those services are called ResourceContainers.
The SecurityContext
class is used to get the user information via the
UserPrincipal
method.
The following 2 methods are used to check authorization:
The isMemberOf(String username, String role)
function that checks if a user belongs to a group (for example, /platform/administrator).
As a result, the user can see the list of users via http://mycompany.com:8080/portal/rest/demo/listusers/0.
The @RolesAllowed({"administrators"})
annotation that allows administrators only to execute http://mycompany.com:8080/portal/rest/demo/hello/eXo.
Edit the resources/conf/portal/configuration.xml
file that declares the REST service component in the portal container.
<?xml version="1.0" encoding="ISO-8859-1"?>
<configuration>
<component>
<type>exo.rest.service.RestUserService</type>
</component>
</configuration>
Build the Maven project using the command: mvn clean install.
Put the .jar
file into the eXo Platform package.
$PLATFORM_TOMCAT_HOME/lib
(in Tomcat).
$PLATFORM_JBOSS_HOME/standalone/deployments/platform.ear!/lib
(in JBoss).
Restart the server, then open http://mycompany.com:8080/portal/rest/demo/listusers/0 in your browser.
If you are not logged in as an admin yet, the [{"rights":"NOT-ALLOWED"}] text will be displayed. This means you do not have right to see the users list.
If you are logged in as an admin, the list of users will be shown, for example: [{"username":"david"},{"username":"james"},{"username":"john"},{"username":"mary"},{"username":"admin"},{"username":"paris"}].