REST
Annotation
|
Description
|
@PATH(your_path)
|
Sets the path to base URL + /your_path. The
base URL is based on your application name, the servlet and the URL pattern
from the web.xml configuration file.
|
@POST, @GET, @PUT, @DELETE
|
Indicates that the following method will answer
to an HTTP POST/GET/PUT/DELETE request, respectively.
|
@Produces(MediaType.TEXT_PLAIN[, more-types])
|
@Produces defines which MIME type is delivered
by a method annotated with @GET.
|
@Consumes(type[, more-types])
|
@Consumes defines which MIME type is consumed
by this method.
|
@PathParam
|
Used to inject values from the URL into a
method parameter. This way you inject, for example, the ID of a resource into
the method to get the correct object.
|
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
//Plain old Java Object it does not extend as class or implements
//an interface
//The class registers its methods for the HTTP GET request using the @GET annotation.
//Using the @Produces annotation, it defines that it can deliver several MIME types,
//text, XML and HTML.
//The browser requests per default the HTML MIME type.
//Sets the path to base URL + /hello
@Path("/hello")
public class Hello {
// This method is called if TEXT_PLAIN is request
@GET
@Produces(MediaType.TEXT_PLAIN)
public String sayPlainTextHello() {
return "Hello Jersey";
}
// This method is called if XML is request
@GET
@Produces(MediaType.TEXT_XML)
public String sayXMLHello() {
return "<?xml version=\"1.0\"?>" + "<hello> Hello Jersey" + "</hello>";
}
// This method is called if HTML is request
@GET
@Produces(MediaType.TEXT_HTML)
public String sayHtmlHello() {
return "<html> " + "<title>" + "Hello Jersey" + "</title>"
+ "<body><h1>" + "Hello Jersey" + "</body></h1>" + "</html> ";
}
}
import static org.junit.Assert.assertEquals;
import java.net.URI;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;
import org.junit.BeforeClass;
import org.junit.Test;
import
com.sun.jersey.api.client.Client;
import
com.sun.jersey.api.client.ClientResponse;
import
com.sun.jersey.api.client.WebResource;
import
com.sun.jersey.api.client.config.ClientConfig;
import
com.sun.jersey.api.client.config.DefaultClientConfig;
public class HelloTest {
private static WebResource service;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
ClientConfig
config = new DefaultClientConfig();
Client
client = Client.create(config);
service = client.resource(getBaseURI());
}
@Test
public void testSayPlainTextHello() {
String
msg = service.path("rest").path("hello")
.accept(MediaType.TEXT_PLAIN).get(ClientResponse.class)
.toString();
System.out.println(msg);
assertEquals(true, msg.contains("200"));
}
private static URI getBaseURI() {
return UriBuilder.fromUri("http://localhost:8080/rest").build();
}
}
|
A more complete example will be a todo service:
package rest.todo;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
// JAX-RS supports an automatic mapping from JAXB annotated class to XML and
// JSON
public class Todo {
private String id;
private String summary;
private String description;
public Todo() {
}
public Todo(String id, String summary) {
this.id = id;
this.summary = summary;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
package rest.todo;
import java.util.HashMap;
import java.util.Map;
public enum TodoDao {
instance;
private Map
contentProvider = new HashMap();
private TodoDao() {
Todo todo = new Todo("1", "Learn REST");
todo.setDescription("Read http://www.vogella.com/tutorials/REST/article.html");
contentProvider.put("1", todo);
todo = new Todo("2", "Do something");
todo.setDescription("Read complete http://www.vogella.com");
contentProvider.put("2", todo);
}
public Map
getModel() {
return contentProvider;
}
}
package rest.todo;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.xml.bind.JAXBElement;
public class TodoResource {
@Context
UriInfo uriInfo;
@Context
Request request;
String id;
public TodoResource(UriInfo uriInfo, Request request, String id) {
this.uriInfo = uriInfo;
this.request = request;
this.id = id;
}
// Application integration
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Todo getTodo() {
Todo todo = TodoDao.instance.getModel().get(id);
if (todo == null)
throw new RuntimeException("Get: Todo with " + id + " not found");
return todo;
}
// for the browser
@GET
@Produces(MediaType.TEXT_XML)
public Todo getTodoHTML() {
Todo todo = TodoDao.instance.getModel().get(id);
if (todo == null)
throw new RuntimeException("Get: Todo with " + id + " not found");
return todo;
}
@PUT
@Consumes(MediaType.APPLICATION_XML)
public Response putTodo(JAXBElement
todo) {
Todo c = todo.getValue();
return putAndGetResponse(c);
}
@DELETE
public void deleteTodo() {
Todo c = TodoDao.instance.getModel().remove(id);
if (c == null)
throw new RuntimeException("Delete: Todo with " + id + " not found");
}
private Response putAndGetResponse(Todo todo) {
Response res;
if (TodoDao.instance.getModel().containsKey(todo.getId())) {
res = Response.noContent().build();
} else {
res = Response.created(uriInfo.getAbsolutePath()).build();
}
TodoDao.instance.getModel().put(todo.getId(), todo);
return res;
}
}
package rest.todo;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.UriInfo;
//Will map the resource to the URL todos
@Path("/todos")
public class TodosResource {
// Allows to insert contextual objects into the class,
// e.g. ServletContext, Request, Response, UriInfo
@Context
UriInfo uriInfo;
@Context
Request request;
// Return the list of todos to the user in the browser
@GET
@Produces(MediaType.TEXT_XML)
public List getTodosBrowser() {
List todos = new ArrayList();
todos.addAll(TodoDao.instance.getModel().values());
return todos;
}
// Return the list of todos for applications
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public List getTodos() {
List todos = new ArrayList();
todos.addAll(TodoDao.instance.getModel().values());
return todos;
}
// to get the total number of records
@GET
@Path("count")
@Produces(MediaType.TEXT_PLAIN)
public String getCount() {
int count = TodoDao.instance.getModel().size();
return String.valueOf(count);
}
@POST
@Produces(MediaType.TEXT_HTML)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public void newTodo(@FormParam("id") String id,
@FormParam("summary") String summary,
@FormParam("description") String description,
@Context HttpServletResponse servletResponse) throws IOException {
Todo todo = new Todo(id, summary);
if (description != null) {
todo.setDescription(description);
}
TodoDao.instance.getModel().put(id, todo);
servletResponse.sendRedirect("../create_todo.html");
}
// Defines that the next path parameter after todos is
// treated as a parameter and passed to the TodoResources
// Allows to type http://localhost:8080/de.vogella.jersey.todo/rest/todos/1
// 1 will be treaded as parameter todo and passed to TodoResource
@Path("{todo}")
public TodoResource getTodo(@PathParam("todo") String id) {
return new TodoResource(uriInfo, request, id);
}
}
And finally a test client:
package rest.todo;
import java.net.URI;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;
import org.junit.BeforeClass;
import org.junit.Test;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
public class TodoTest {
private static WebResource service;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
service = client.resource(getBaseURI());
}
@Test
public void test() {
// Get XML
System.out.println(service.path("rest").path("todo")
.accept(MediaType.TEXT_XML).get(String.class));
// Get XML for application
System.out.println(service.path("rest").path("todo")
.accept(MediaType.APPLICATION_JSON).get(String.class));
// Get JSON for application
System.out.println(service.path("rest").path("todo")
.accept(MediaType.APPLICATION_XML).get(String.class));
}
private static URI getBaseURI() {
return UriBuilder.fromUri(
"http://localhost:8080/rest").build();
}
}