adam bien's blog

The Executable Feel Of JAX-RS 2.0 Client 📎

JAR-RS 2.0 comes with a standardized client. Instead of directly using Jersey, CXF or RESTEasy implementation you can now use these libraries as Service Provider Interface (SPI) over a standardized API:

import java.util.List;
import javax.ws.rs.client.Client;
import static javax.ws.rs.client.Entity.entity;
import javax.ws.rs.client.Target;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ClientFactory;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;

public class ScriptingResourceTest {

    private Client client;
    private String baseURI = "http://localhost:8080/lightfish/resources/scripts";
    private Target target;
            
    @Before
    public void init(){
        this.client = ClientFactory.newClient();
        this.target = this.client.target(baseURI);
    }

    @Test
    public void crudScript(){
        String scriptName = "duke"+System.currentTimeMillis();
        Script origin = new Script(scriptName, "true",true);
        
        //PUT
        Response response = this.target.request().put(entity(origin,MediaType.APPLICATION_XML));
        assertThat(response.getStatus(),is(Status.CREATED.getStatusCode()));
        String location = response.getHeaders().getHeader("Location");
        assertTrue(location.endsWith(scriptName));
        
        //GET
        Script fetched = this.client.target(location).request(MediaType.APPLICATION_XML).get(Script.class);
        assertThat(fetched,is(origin));

        //GET (ALL)
        GenericType<List<Script>> list = new GenericType<List<Script>>() {};
        List<Script> result = this.target.request(MediaType.APPLICATION_XML).get(list);
        assertFalse(result.isEmpty());
        
        //DELETE
        response = this.target.path(scriptName).request().delete();
        assertThat(response.getStatus(),is(Status.OK.getStatusCode()));
        
        //GET
        Response notExistingEntity = this.client.target(location).request(MediaType.APPLICATION_XML).get();
        assertThat(notExistingEntity.getStatus(),is(Status.NO_CONTENT.getStatusCode()));
    }
}

The system test above remotely interacts with the following JAX-RS resource:

@Stateless
@Path("scripts")
@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
@Consumes({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
public class ScriptingResource {
 
    
    @GET
    public List<Script> scripts(){
    }

    @GET
    @Path("{id}")
    public Script script(@PathParam("id") String id){
    }
    
    @PUT
    public Response save(Script script){
    }

    @DELETE
    @Path("{name}")
    public Response delete(@PathParam("name") String name){
    }
}

The code is executable. Jersey implementation of JAX-RS 2.0 API already resides in maven central:

<dependency>
  <groupId>org.glassfish.jersey.core</groupId>
  <artifactId>jersey-client</artifactId>
  <version>2.0-m02</version>
  <scope>test</scope>
</dependency>

The class ScriptingResourceTest was taken from the LightFish project and used to system test the scripting subsystem.