A simple introduction to RESTful WEB Services
REST was presented in 2000 by Roy Fielding in his doctoral dissertation, one of the chief authors of the HTTP Specification version 1.0 and 1.1.
The most important concept in REST is resources, which are identified by using a global ID (usually a URI).
The client application uses the HTTP method ( GET/ POST/ PUT/ DELETE
) to manipulate the resource or resource set. RESTful Web services are Web services that are implemented using HTTP and REST principles. In general, RESTful Web Services should define the following:
- The base/root URI of the Web service, for example Http://host/<appcontext>/resources.
- Supports MIME-type response data. Contains Json/xml/atom and so on.
- The set of operations supported by the service (for example,
POST、GET、PUT
or DELETE
).
Table 1 illustrates the resource URIs and HTTP methods used in a typical RESTful Web service.
Table 1. Example of a RESTful Web service demo
Methods/Resources | A
collection of resources. URIs such as: Http://host/<appctx>/resources |
member resource, URI such as: http://host/<appctx>/resources/1234 |
GET |
Lists all members of the resource collection. |
Retrieves a representation of a resource identified as 1234. |
PUT |
An update (replace) with a collection also has a collection. |
Update the digital resource labeled 1234. |
POST |
Creates a digital resource in the collection whose ID is assigned on its own initiative. |
Create a child resource in the following. |
DELETE |
Deletes the entire collection of resources. |
Delete the digital resource labeled 1234. |
JSR 311 (jax-rs) and Jersey
The proposal for JSR 311 or Jax-rs (Java API for RESTful Web Services) started in 2007, and the 1.0 version was finalized by October 2008. Now. The JSR 311 version number 1.1 is also in the draft stage. The purpose of the JSR is to provide a set of APIs to simplify the development of restful WEB services.
Prior to the JAX-RS specification, frameworks such as Restlet and Resteasy have been available to help you implement RESTful WEB services. But they're not intuitive enough. Jersey is the jax-rs of the implementation of the test. It consists of three main parts.
- Core server: By providing standardized gaze and API standardization in JSR 311, you can develop RESTful Web services in an intuitive way.
- Core client: The Jersey client API helps you communicate easily with REST services.
- Integration (integration): Jersey also provides libraries that can easily integrate the Spring, Guice, Apache Abdera.
In the following sections of this article, I covered all of these components, but more focused on core server.
Building RESTful Web Services
I'll start with a "Hello World" application that can be integrated into Tomcat.
The application will lead you through the process of setting up the environment and involves the basics of Jersey and Jax-rs.
I'll then cover more complex applications, delving into the nature and features of Jax-rs, such as multiple MIME-type representation support, JAXB support, and so on. I'll take some code snippets from the example to introduce the important concepts.
Hello World: First Jersey Web project
To set up the development environment. Here's what you need:
- Ide:eclipse IDE for JEE (v3.4+) or IBM Rational application Developer 7.5
- Java SE5 or higher version number
- Web Container: Apache Tomcat 6.0 (Jetty and others can also)
- Jersey Library: Jersey 1.0.3 archive, including all required libraries
Setting the Jersey Environment
First, the server execution is created for Tomcat 6.0 on Eclipse.
This is the Web container for RESTful Web applications.
Then create an application named "Jersey" and specify the target as Tomcat 6.0 when it executes.
At last. Copy the following library from the Jersey development package to the Library folder under Web-inf:
- Core server: Jersey-core.jar. Jersey-server.jar,jsr311-api.jar. Asm.jar
- Core client: (for testing) Jersey-client.jar
- JAXB support: (used in the advanced example) Jaxb-impl.jar,jaxb-api.jar. Activation.jar,stax-api.jar. Wstx-asl.jar
- JSON support: (used in advanced examples) Jersey-json.jar
Developing REST Services
Now. You have set up the environment for developing your first REST service. The service issues "Hello" to the client.
To do this, you need to send all the REST requests to the Jersey container--Define the servlet scheduler in the application's Web. xml file (see Listing 1). In addition to declaring the Jersey servlet, it also defines an initialization parameter that indicates the Java package that includes the resource.
Listing 1. Define the Jersey servlet dispatch level in the Web. xml file
<servlet> <servlet-name>jersey REST service</servlet-name><servlet-class> com.sun.jersey.spi.container.servlet.servletcontainer</servlet-class> <init-param> < Param-name>com.sun.jersey.config.property.packages</param-name> <param-value> sample.hello.resources</param-value> </init-param> <load-on-startup>1</ load-on-startup></servlet><servlet-mapping> <servlet-name>jersey REST Service</ Servlet-name> <url-pattern>/rest/*</url-pattern></servlet-mapping>
Now you will write a resource named Helloresource that accepts HTTP GET
and responds to "Hello Jersey".
Listing 2. Helloresource in the Sample.hello.resources package
@Path ("/hello") public class Helloresource {@GET @produces (mediatype.text_plain) public String SayHello () {return "Hello Jersey ";}}
There are several places in the code that need to be emphasized:
- Resource Class (Resource Class): Note that the resource class is a simple Java object (POJO). can be implemented regardless of interface. This adds a number of advantages, such as reusability and simplicity.
- Gaze (Annotation): Defined in javax.ws.rs.*, is part of the Jax-rs (JSR 311) specification.
@Path
: Defines the resource base URI. Consists of the upper and lower root and the hostname, and the resource identifier is similar to Http://localhost:8080/Jersey/rest/hello.
@GET:
This means that the following method responds to the HTTP GET
method.
@Produces:
Defines the response content MIME type in plain text mode.
Test Hello App
To test the application, be able to open your browser and enter the URL Http://
The following section will cover the necessary parts of the JAX-RS specification. Use the code snippet in the Contacts demo example application to describe it.
You can find all the code in this advanced example in the source package
Resources
Resources are a critical part of a RESTful Web service.
You can use HTTP methods, such as and, to GET、POST、PUT
DELETE
manipulate resources.
All the content in the application is resources: employees, contacts, organizations, and so on.
In Jax-rx, resources are implemented through POJO. Use @Path
gaze to compose its identifier . Resources can have child resources.
In such a case. A parent resource is a collection of resources, and a child resource is a member resource.
In the example Contacts application, you will manipulate personal contacts and contact collections.
ContactsResource
is a collection resource that consists of a/contacts URI. ContactResource
is a member resource consisting of a/contacts/{contactid} URI. Underline JavaBean is a simple contact class that uses the ID, name, and address as the member field.
See listing 3 and Listing 4 for details.
Listing 3. Contactsresource
@Path ("/contacts") public class Contactsresource {@ContextUriInfo uriinfo; @ContextRequest request; @GET @produces ({ Mediatype.application_xml, Mediatype.application_json}) public list<contact> getcontacts () {List<Contact > contacts = >new arraylist<contact> (); Contacts.addall (Contactstore.getstore (). values ()); return Contacts;} @Path (' {contact} ') public Contactresource getcontact (@PathParam ("contact") String "{return new Contactresource (Uriinfo, request, contact);}}
There are several interesting places to watch out for.
@Context:
Use this gaze to inject context objects, such as Request, Response, Uriinfo, ServletContext, and so on.
@Path("{contact}"):
This is the @Path
gaze. A URI that is combined with the root path "/contacts" to form a child resource.
@PathParam("contact"):
The gaze will inject the path of the number of parameters into the method, in this case the contact ID. Other available gaze has @FormParam
, @QueryParam
and so on.
@Produces:
The response supports multiple MIME types. In this example and in the previous demo sample. The application/xml will be the default MIME type.
You may also have noticed. GET
method returns a custom Java object instead of a String (plain text). As seen in the previous Hello World Demo sample.
The JAX-RS specification requires implementations to support multiple representation types. For example, InputStream, byte[], JAXB elements, JAXB element collections, and so on, and the ability to serialize them as XML, JSON, or plain text as a response. I will provide a number of other information about presentation techniques, especially the JAXB element representation, below.
Listing 4. Contactresource
public class Contactresource {@ContextUriInfo uriinfo; @ContextRequest request; String Contact;public contactresource (uriinfo uriinfo, request request, String contact) {this.uriinfo = Uriinfo; This.request = Request;this.contact = contact;} @GET @produces ({mediatype.application_xml, mediatype.application_json}) Public Contact GetContact () {Contact Cont = Contactstore.getstore (). Get (Contact), if (cont==null) throw new Notfoundexception ("No such contact."); return cont;}}
Contactresource's code is simple and straightforward. Note the following:
- Representation Type Contact:contact is a simple JavaBean, by
@XmlRootElement
gazing, which enables it to be expressed as XML or JSON.
- Contactstore: This is a HASHMAP-based memory data repository, which is not really important for this article.
Method
The HTTP method maps to the CRUD (create, read, update, and DELETE) operations of the resource. While you can make minor changes, PUT
such as making a method a creation or an update, the main pattern is the following:
- HTTP
GET
: Gets/Lists/retrieves a single resource or collection of resources.
- HTTP
POST
: New resource.
- HTTP
PUT
: Updates an existing resource or resource collection.
- HTTP
DELETE
: Deletes a resource or a collection of resources.
Because I've already covered the GET
method. I will explain from the beginning POST
. Just like any other method. I still use the contact Demo sample to illustrate.
POST
You typically create a new contact by filling out a form. Other words. The HTML form will POST to Server,server to create and maintain the newly created contacts.
Listing 5 shows the server-side logic for the operation.
Listing 5. Accept form submission (POST) and create a new contact
@POST @produces (mediatype.text_html) @Consumes (mediatype.application_form_urlencoded) public void NewContact (@ Formparam ("id") string ID, @FormParam ("name") string name, @Context HttpServletResponse servletresponse) throws IOException {Contact c = new Contact (id,name,new arraylist<address> ()); Contactstore.getstore (). Put (ID, c); Uri uri = Uriinfo.getabsolutepathbuilder (). path (ID). build (); Response.created (URI). build (); Servletresponse.sendredirect (".. /pages/new_contact.html ");}
Note the following section of the Demo sample:
@Consumes:
Declares that the method uses HTML FORM.
@FormParam:
Injects the HTML property of the method to determine the form input.
@Response.created(uri).build():
Build a new URI for the newly created contact ( /contacts/{id}
) and set the response code ( 201/created
). You can use http://localhost:8080/jersey/rest/contacts/<id> to access new contacts.
PUT
I use the PUT method to update an existing resource. However, it can also be implemented by updating. or create a resource as shown in the code snippet in Listing 6.
Listing 6. Accept PUT requests and create or update contacts
@PUT @consumes (mediatype.application_xml) public Response putcontact (jaxbelement<contact> jaxbcontact) { Contact C = Jaxbcontact.getvalue (); return Putandgetresponse (c);} Private Response Putandgetresponse (contact c) {Response res;if (Contactstore.getstore (). ContainsKey (C.getid ())) {res = Response.nocontent (). build ();} else {res = response.created (Uriinfo.getabsolutepath ()). build ();} Contactstore.getstore (). Put (C.getid (), c); return res;}
I've also included a number of different concepts in this demo sample, highlighting the following concepts:
DELETE
The implementation DELETE
method is easy.
See listing 7 for a demo sample.
Listing 7. Delete the contact whose ID is determined
@DELETEpublic void DeleteContact () {Contact c = contactstore.getstore (). remove (contact); if (c==null) throw new Notfoundexception ("No such contact.");
Representation
In the previous section, I introduced several representation types.
Now I'll briefly browse through and delve into the JAXB representation. Other supported representations are byte[], InputStream, File, and so on.
- String: Plain text.
- Response: Generic HTTP response, including custom content with different response codes.
- void: Empty response with 204/no content status code.
- Resource class: Entrust the process to the resource class.
- POJO: Use
@XmlRootElement
the gaze of the JavaBean. This makes it a JAXB bean. Ability to bind to XML.
- POJO collection: JAXB Bean collection.
Jax-rs supports using JAXB (Java API for XML binding) to bind JavaBean to XML or JSON. Vice versa. JavaBean must use @XmlRootElement
gaze. Listing 8 uses the contact Bean as a demo sample.
A field that does not understand @XmlElement
the gaze will include an XML element with the same name. Listing 9 shows the serialized XML and JSON representations for a contact bean.
The contact collection is represented by the same, using <Contacts> as the wrapper element by default.
Listing 8. Contact Bean
@XmlRootElementpublic class Contact {private String Id;private string Name;private list<address> addresses;public Contact () {}public contact (string ID, string name, list<address> addresses) {this.id = Id;this.name = name;this.addr Esses = addresses;} @XmlElement (name= "address") public list<address> getaddresses () {return addresses;} public void setaddresses (list<address> addresses) {this.addresses = addresses;} Omit other getters and setters}
Listing 9. Representation of a contact
XML representation:<contact> <address> <city>Shanghai</city> <street> Long Hua street</street> </address> <address> <city>Shanghai</city> <street>dong Quan street</street> </address> <id>huangyim</id> <name>huang Yi ming</name></contact>json representation:{"Contact": [{"Address": [{"City": " Shanghai "," Street ":" Long Hua Street "},{" City ":" Shanghai "," Street ":" Dong Quan Street "}]," id ":" Huangyim " , "name": "Huang Yi Ming"}]}
Client communicating with the REST service
In the demo sample so far, I've developed a RESTful Web service that supports CRUD.
Now I'm beginning to explain how to communicate with the REST service using curl and the Jersey client API. In this way, I was able to test server-side code and introduce many other information about client technology.
Using curl to communicate with REST services
Curl is a popular command-line tool that can send requests to servers that use the HTTP and HTTPS protocols. This is a good tool for communicating with RESTful Web services. Because it can send content by whatever HTTP method.
Curl is already self-contained in Linux and Mac. And there is a useful tool. Can be in Windows? Installed on the platform.
Today, we initialize the first Curl command to get all the contacts. You can refer to listing 3 for the server-side code.
curl http://localhost:8080/Jersey/rest/contacts
The response uses XML and includes all contacts.
Note that the getContacts()
method also generates a Application/json MIME-type response.
You can also request content of that type.
curl –HAccept:application/json http://localhost:8080/Jersey/rest/contacts
The response will be a JSON string that includes all the contacts.
Today, I will be PUT
a new contact person. Attention. The method in Listing 6 putContact()
accepts the XML and uses JAXB to bind the XML to the contact object.
Curl-x put-hcontent-type:application/xml--data "<contact><id>foo</id> <name>bar</ Name></contact> "Http://localhost:8080/Jersey/rest/contacts/foo
A new contact identified by "Foo" will be added to the contact repository.
You can use Uri/contacts or/contacts/foo to validate a contact collection or a single contact.
Communicating with the REST service using the Jersey Client
Jersey also provides a client library to help you communicate with the server and unit test the RESTful service. The Library is a general implementation that can integrate whatever http/https-based Web services.
The core class of the client is the WebResource
class. You can use this class to build a request URL from the root URI, and then send the request and get the response. Listing 10 shows how to create an WebResource
instance.
Note WebResource
is a large object, so it is created only once.
Listing 10. Creating an WebResource instance
Client C = client.create (); WebResource R=c.resource ("http://localhost:8080/Jersey/rest/contacts");
The first Jersey client Demo sample sends a GET
request for all contacts and prints the response status code and response content, as shown in Listing 11.
Listing 11. GET All contacts and print responses
Clientresponse response = R.get (Clientresponse.class); System.out.println (Response.getstatus ()); System.out.println (Response.getheaders (). Get ("Content-type")); String entity = response.getentity (String.class); SYSTEM.OUT.PRINTLN (entity);
Listing 12 shows an example of a demo that creates a new contact identified by "foo".
Listing 12. Create a contact
Address[] Addrs = {new Address ("Shanghai", "Ke Yuan Street")}; Contact C = new Contact ("foo", "foo Bar", Arrays.aslist (Addrs)); Clientresponse response = R.path (C.getid ()). Accept (Mediatype.application_xml). Put (Clientresponse.class, c); System.out.println (Response.getstatus ());
Note WebResource
The API for the instance. It constructs a URI. Sets the request header and invokes the request in a single line of code. The content (contact object) binds itself to XML.
Listing 13 shows the last demo sample that retrieves a contact identified by "Foo" (created in the previous demo sample) and then deletes the contact.
Listing 13. Retrieve the "foo" contact and delete
generictype<jaxbelement<contact>> generic = new generictype<jaxbelement<contact>> () {}; jaxbelement<contact> jaxbcontact = R.path ("foo"). Type (Mediatype.application_xml). get (generic); Contact contact = Jaxbcontact.getvalue (); System.out.println (Contact.getid () + ":" + contact.getname ()); Clientresponse response = R.path ("foo"). Delete (Clientresponse.class); System.out.println (Response.getstatus ());
Attention. When you want to get the JAXB bean response, you need to use the Paradigm feature introduced in Java 2 Platform, Standard Edition (J2SE).
Use the Jersey client to practice these demo examples.
You can find many other example code in the resource bundle.
Also can visit Jersey site to see a lot of other information.
Conclusion
Jersey can integrate with other frameworks or useful tool libraries using the Jersey integration Library.
For now, Jersey can integrate Spring, Guice, and the integration of ATOM representations with Apache-adbera.
The API and Getting Started Guide can be found on the Jersey Project homepage.
Original link:
http://www.ibm.com/developerworks/cn/web/wa-aj-tomcat/#resources
Download
Descriptive narrative |
name |
size |
Source |
Jersey.Sample.Contact.Src.zip |
10KB |
Building RESTful Web Services using Jersey and Apache Tomcat