Creating RESTful Web Services with Java technology-reproduced

Source: Internet
Author: User
Tags http post

Brief introduction

Jax-rs (JSR-311) is a specification for RESTful service capabilities in a Java EE environment. It can provide a viable alternative to traditional SOAP-based Web services.

In this article, learn about the main components of Jax-rs. This article shows an example of how an enterprise can use features within JAX-RS to expose employee contact information in a Restful way.

Background

Over the years, developers have used various tools to create RESTful services within their Java applications. Because of the simplicity of the REST architecture, the primary requirement-the ability to receive HTTP messages and headers-can be implemented by a simple Java Web container.

Java Servlets is often used to develop RESTful applications. There is no fixed pattern for how to use Servlets. Typically, the servlet accepts the request and resolves the HTTP request URI itself to match the request to a known resource. For REST service development, this simple servlet model is extended with a more formal API. However, because these APIs were developed on top of the servlet model, none of these APIs was developed as a formal standard.

As rest is increasingly being adopted as an architecture, Java Community Process (JCP) plans to include formal support for rest in the future Java Enterprise Edition 6 release. JSR-311 has also been created and has the JAX-RS 1.0 specification, providing a new annotation-based approach to developing RESTful services. Jax-rs annotations allow you to focus on your resources and data objects compared to the servlet model. Also, you no longer have to develop the communication layer (via servlet).

Back to top of page

Java Resources

Jax-rs has created a special language to describe resources, as represented by its programming model. There are five main entries: the root resource, the child resource, the resource method, the child resource method, and the child resource Locator.

Root Resource

The root resource is a @Path Java class that is annotated by. The @Path comment provides a value property that indicates the path to which this resource resides. A value property can be a literal character, a variable, or a variable plus a custom regular expression. Listing 1 shows an example.

Listing 1. Jax-rs Root Resources
Package Com.ibm.jaxrs.sample.organization;import Javax.ws.rs.Path; @Path (value= "/contacts")public class Contactsresource {...}
Child Resources

The child resource is the Java class returned as a result of the Subresource locator call. They are similar to root resources, except that they @Path are not annotated because their paths are given by the child resource Locator. A child resource typically contains methods that are annotated by the HTTP request method designator (designator) to serve this request. If they do not contain such annotated methods, they will further resolve this resource processing request by assigning it to the appropriate child resource locator.

Listing 2. Jax-rs Child Resources
Package Com.ibm.jaxrs.sample.organization;import Javax.ws.rs.get;public class Department {@GETpublic String Getdepartmentname () {...}}

Listing 2, shown above, shows the ContactsResource.getContactDepartment child resources returned by the method. In this example, if an HTTP GET request is sent to the /contact/{contactName}/department path, the Department resource method within the child resource getDepartmentName processes the request.

Resource methods

A resource method is a Java method that is bound to an HTTP method within a root resource or child resource. Bindings are done through @GET annotations such as this.

Listing 3. Jax-rs Resource Methods
Package Com.ibm.jaxrs.sample.organization;import Java.util.list;import Javax.ws.rs.get;import javax.ws.rs.Path;@ Path (value= "/contacts") public class Contactsresource {@GETpublic list<contactinfo> getcontacts () {...}}

In the example in Listing 3, the /contacts HTTP GET request sent to the path will be getContacts() processed by the resource method.

Child resource Methods

The child resource method is very similar to a resource method; the only difference is that the child resource method is also @Path annotated, and this comment further qualifies the method's selection.

Listing 4. Jax-rs Child Resource Method
Package Com.ibm.jaxrs.sample.organization;import Java.util.list;import Javax.ws.rs.get;import javax.ws.rs.Path;@ Path (value= "/contacts") public class Contactsresource {@GETpublic list<contactinfo> getcontacts () {...} @GET @path (value= "/ids") public list<string> Getcontactids () {...}}

In Listing 4, the /contacts/ids HTTP GET request sent to the path will be processed by the getContactIds() child resource method.

Sub-Resource Locator

A child resource locator is some way to further parse the resources used to process a given request. They are very similar to child resource methods because they have a @Path comment but do not have an HTTP request method indicator, such as a @GET comment.

Listing 5. Jax-rs Sub-Resource Locator
Package Com.ibm.jaxrs.sample.organization;import Java.util.list;import Javax.ws.rs.get;import Javax.ws.rs.Path; Import Javax.ws.rs.PathParam; @Path (value= "/contacts") public class Contactsresource {@GETpublic list<contactinfo > Getcontactss () {...} @GET @path (value= "/ids") public list<string> Getcontactids () {...} @Path (value= "/contact/{contactname}/department") Public department Getcontactdepartment (@PathParam (value= " ContactName ") String contactName) {...}}

In the above example, /contact/{contactName}/department any HTTP request to the path will be processed by the getContactDepartment child Resource Locator. {contactName}section indicates that contact the path section can then be any valid URL value.

Back to top of page

Comments

This section will explore some important annotations and their use. For a complete list of annotations provided by the JAX-RS specification, you can refer to the JSR-311 link given in the Resources section of this article.

@Path

@PathAnnotations are used to describe the location of a root resource, a child resource method, or a child resource. valuevalues can contain text characters, variables, or variables that have custom regular expressions. The example in Listing 6 shows the @Path main application of annotations.

Listing 6. Use of @Path
Package Com.ibm.jaxrs.sample.organization;import Java.util.list;import Javax.ws.rs.get;import Javax.ws.rs.Path; Import Javax.ws.rs.PathParam; @Path (value= "/contacts")public class Contactsresource {@GET@Path (value= "/{emailaddress:[email Protected]+\\. [a-z]+}] public contactinfo getbyemailaddress (@PathParam (value= "EmailAddress") String EmailAddress) {...} @GET@Path (value= "/{lastname}")public ContactInfo getbylastname (@PathParam (value= "LastName") String LastName) {...}}

ContactsResourceThe comment on the class indicates that /contacts all requests to the path will be processed by the ContactsResource root resource. getByEmailAddressthe @Path comment on indicates that any request sent to /contacts/{emailAddress} (which emailAddress represents a regular expression [email protected]+\\.[a-z]+ ) will be processed by the getByEmailAddress .

getByLastNameThe comment on the method @Path specifies that all requests sent to the /contacts/{lastName} path (which lastName represent a getByEmailAddress valid URL part that does not match the inside regular expression) will be processed by the getByLastName method.

@GET, @POST, @PUT, @DELETE, @HEAD

@GET, @POST, @PUT, @DELETE, and @HEAD are all HTTP Request method indicator comments. You can use them to bind Java methods and HTTP request methods within a root resource or child resource. HTTP GET requests are mapped to methods that are annotated by @GET, HTTP POST requests are mapped to methods that are annotated by @POST, and so on. Users may also need to @HttpMethod define their own custom HTTP request method indicators by using annotations.

Listing 7. Custom HTTP Request Method Indicator comments
Package Com.ibm.jaxrs.sample.organization;import Java.lang.annotation.elementtype;import Java.lang.annotation.retention;import Java.lang.annotation.retentionpolicy;import Java.lang.annotation.Target; Import Javax.ws.rs.HttpMethod; @Retention (retentionpolicy.runtime) @Target (Elementtype.method) @HttpMethod ("GET") Public @interface Customget {}

The declaration above defines a @CustomGET comment. This comment will have the same semantic value as the @GET annotation and can be used in its place.

@Conumes and @Produces

@ConsumesThe comment represents a MIME type that a resource can accept. @Producesthe comment represents a MIME type that a resource can return. These annotations can be found within a resource, resource method, child resource method, sub-resource locator, or sub-resource.

Listing 8. @Consumes/@Produces
package com.ibm.jaxrs.sample.organization;import java.util.list;import Javax.ws.rs.consumes;import Javax.ws.rs.get;import Javax.ws.rs.path;import Javax.ws.rs.pathparam;import Javax.ws.rs.Produces, @Path (value= "/contacts") public class Contactsresource {@GET @Path (value= "/{emailaddress:[ Email protected]+\\. [a-z]+}]  @Produces (value={"Text/xml", "Application/json"})  public contactinfo getbyemailaddress (@ Pathparam (value= "EmailAddress") String EmailAddress) {...} @GET @path (value= "/{lastname}")  @Produces (value= "Text/xml")  public contactinfo getbylastname (@ Pathparam (value= "LastName") String lastName) {...} @POST  @Consumes (value={"Text/xml", "Application/json"})  public void Addcontactinfo (ContactInfo ContactInfo) {...}} 

For the above getByEmailAddress and the addContactInfo methods, they can be processed text/xml and application/json . The received or returned resource representation will depend on the HTTP request header set by the client. @Consumesthe comment Content-Type matches the request header to determine whether the method can accept the contents of a given request.

In Listing 9, application/json the Content-Type header plus the POST to the path /contacts indicates that the ContactsResource method within our class addContactInfo will be called to process the request.

Listing 9. Use of Content-type Head
Post/contacts http/1.1Content-type:application/jsoncontent-length:32

Instead, the @Produces comment is matched against the Accept request header to determine whether the client can handle the representation returned by the given method.

Listing 10. Use of the Accept head
Get/contacts/[email protected] http/1.1Accept:application/json

In Listing 10, the request to/contacts/[email protected] indicates that the method will be GET getByEmailAddress called and the returned format will be application/json , not text/xml.

Back to top of page

Providers

JAX-RS providers are application components that allow customization of runtime behavior in three key areas: data binding, exception mapping, and context resolution (for example, providing a Jaxbcontext instance to the runtime). Each JAX-RS provider class must be @Provider commented by. The following example discusses two data binding providers MessageBodyWriter and MessageBodyReader .

Messagebodywriter

Messagebodywriters is used by the JAX-RS runtime to serialize the representation of the returned resource. The JSR-311-compliant runtime provides native support for common types (java.lang.String, Java.io.InputStream, JAXB objects, and so on), but users can also provide the Jax-rs runtime with his or her own Messagebodywriter. For example, you can provide a customization MessageBodyWriter to handle a custom ContactInfo Java type, as shown below.

Listing 11. Custom Messagebodywriter
Package Com.ibm.jaxrs.sample.organization;import Javax.ws.rs.consumes;import Javax.ws.rs.produces;import Javax.ws.rs.ext.messagebodywriter;import Javax.ws.rs.ext.Provider; @Provider @produces ("Text/xml") public class Contactinfowriter implements messagebodywriter<contactinfo> {public longgetsize (T T, java.lang.class< contactinfo> type, Java.lang.reflect.Type generictype, java.lang.annotation.annotation[] annotations, mediatype MediaType) {...} public boolean iswriteable (java.lang.class<contactinfo> type, Java.lang.reflect.Type generictype, Java.lang.annotation.annotation[] Annotations, mediatype mediatype) {return true;} public void WriteTo (ContactInfo contactinfo, java.lang.class<contactinfo> type, Java.lang.reflect.Type GenericType, java.lang.annotation.annotation[] annotations, mediatype mediatype, multivaluedmap<java.lang.string , java.lang.object> httpheaders, Java.io.OutputStream entitystream) {contactinfo.serialize (Entitystream);}}

ContactInfoWriterCalled by the Jax-rs runtime before the returned resource representation is serialized. If it isWriteable returns True and @Produces is the closest match to the value of this resource method @Produces , the writeTo method is called. Here, you are ContactInfoWriter responsible for serializing the contents of the instance to the underlying OutputStream ContactInfo .

Messagebodyreader

Messagebodyreaders is the opposite of messagebodywriters. For deserialization, the JAX-RS runtime supports the same type as serialization. The user can also provide his or her own messagebodyreader implementation. The primary function of the messagebodyreader is to read the request InputStream and deserialize the incoming bytes into a Java object expected by this resource method. ContactInfothe type MessageBodyReader can be similar to listing 12.

Listing 12. Custom Messagebodyreader
package com.ibm.jaxrs.sample.organization;import javax.ws.rs.consumes;import Javax.ws.rs.produces;import javax.ws.rs.ext.messagebodyreader;import Javax.ws.rs.ext.Provider, @Provider @consumes ("Text/xml") public class Contactinforeader implements messagebodyreader<contactinfo> {public Boolean isreadable (java.lang.class<contactinfo> type, Java.lang.reflect.Type generictype, java.lang.annotation.annotation[] Annotations, mediatype mediatype) {return true;} Public ContactInfo Readfrom (java.lang.class<contactinfo> type, Java.lang.reflect.Type generictype, Java.lang.annotation.annotation[] Annotations, mediatype mediatype, multivaluedmap<java.lang.string, Java.lang.string> httpheaders, Java.io.InputStream entitystream) {return contactinfo.parse (Entitystream);}} 

isWriteablea method similar to ContactInfoReader Messagebodywriter isReadable will be called to determine whether Messagebodyreader can handle this input. If isReadable true is returned and the @Consumes value matches the value of this resource method @Consumes , it is selected ContactInfoReader . When the readFrom method is called, the result is an InputStream instance created based on the requested content ContactInfo .

Back to top of page

Configuration

At this point, we explored the Jax-rs resource class and some provider classes (Messagebodyreaders and messagebodywriters). So, how do you configure these classes within the Jax-rs runtime? This can be achieved by extending the Javax.ws.rs.core.Application class. This class provides a set of classes or a set of singleton (Singleton) object instances, including all root-level resources and providers (by @Provider the annotated Class) within a JAX-RS application. If you extend this application class for this example contact information application, it should look like listing 13.

Listing 13. Contactinfoapplication
Package Com.ibm.jaxrs.sample.organization;import Java.util.hashset;import Java.util.set;import Javax.ws.rs.core.application;public class Contactinfoapplicaiton extends application {public set<class<?> > getclasses () {set<class<?>> classes = new hashsetset<class<?>> (); Classes.add ( Contactsresource.class); Classes.add (Contactinfowriter.class); Classes.add (Contactinforeader.class);} Public setset<object<?>> getsingletons () {//Nothing to do, no singletons}}

getClassesThe Jax-rs method provides a set of classes available to the runtime for metadata. Notice that the getSingletons method does not return anything. In general, it is no problem to treat a jax-rs provider as a singleton, but it is prudent to treat a jax-rs resource as a singleton. Note-based injection, which is often used by the Jax-rs resource class, may not be supported in the case of a singleton instance. Therefore, you should avoid using singleton instances of JAX-RS resources unless you plan carefully.

Assuming that you are deploying a JAX-RS application within a servlet container, there are two ways to register your javax.ws.rs.core.Application subclass with the Jax-rs runtime. This is handled by the Web. XML of the WAR file, as shown below.

Listing 14. A servlet container that cannot perceive jax-rs
<web-app id= "webapp_id" version= "2.5" xmlns= "Http://java.sun.com/xml/ns/javaee" xmlns: Xsi= "Http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation= "Http://java.sun.com/xml/ns/javaee/http Java.sun.com/xml/ns/javaee/web-app_2_5.xsd "><servlet><servlet-name>contactinfoservlet</ servlet-name><servlet-class>com.sample.restsystemservlet</servlet-class><init-param>< Param-name>javax.ws.rs.application</param-name><param-value> Com.ibm.jaxrs.sample.organization.contactinfoapplication</param-value></init-param></servlet ><servlet-mapping><servlet-name>contactinfoservlet</servlet-name><url-pattern>/* </url-pattern></servlet-mapping></web-app> 

Within a servlet container that is considered Jax-rs-aware, the application subclass name should be provided as init-param within the servlet definition. The name of the Init-param must be javax.ws.rs.Application. The Servlet class is most likely the Jax-rs runtime system servlet. You can list each of the possible URL patterns, or use /* wildcards to register as shown below.

Listing 15. A servlet container that can perceive jax-rs
<web-app id= "webapp_id" version= "2.5" xmlns= "Http://java.sun.com/xml/ns/javaee" xmlns:xsi= "http://www.w3.org/ 2001/xmlschema-instance "xsi:schemalocation=" Http://java.sun.com/xml/ns/javaee Http://java.sun.com/xml/ns/javaee /web-app_2_5.xsd "><servlet><servlet-name>ContactInfoServlet</servlet-name>< Servlet-class>com.ibm.jaxrs.sample.organization.contactinfoapplication</servlet-class></servlet ><servlet-mapping><servlet-name>contactinfoservlet</servlet-name><url-pattern>/* </url-pattern></servlet-mapping></web-app>

Within a servlet container that is considered to be capable of perceiving jax-rs, the application subclass name must be provided as the value of the servlet class element within the servlet definition. You can still choose whether to list each possible URL pattern or use a /* wildcard character to register.

Back to top of page

Using Apache Wink as the runtime Jax-rs

The next step is to find a runtime that supports the available features within the JAX-RS. The Apache Wink Project provides a runtime that satisfies this requirement, with all of the features described above (see Resources). Initially, Wink was a collaborative project initiated by multiple vendors and members of the open source community. The goal of the project is to provide the most flexible and lightweight runtime.

In addition to the standard Jax-rs features, Wink also provides enhanced support for JSON, Atom, and RSS serialization formats. The JAX-RS itself does not provide the client API, but Wink includes its own model of the client API and is completely resource-centric.

To simplify the development of Wink-based services, you can download Wink 1.0 libraries and include them as the default Jax-rs libraries into the Rational application Developer (RAD) 7.5.5 development environment (see Resources). In this updated version, RAD adds a jax-rs facet that you can configure to support validators and annotation help. This new facet also simplifies the configuration of the servlet by automatically generating the required servlet entries and mappings.

Conclusion

Compared to the traditional servlet model, JAX-RS provides a viable, simpler, and more portable way to implement RESTful services within Java. Using annotations allows you to easily provide path locations for Java resources and bind Java methods to HTTP request methods. A portable data-binding architecture provides some native Java type support and allows for full customization of serialization/deserialization processing. The extension of the Javax.ws.rs.core. Application subclass and the corresponding inventory within Web. XML indicate that a minimal deployment descriptor configuration makes it easy to deploy.

This article only covers part of the functionality that JAX-RS can provide. The other two Jax-rs provider types ContextResolvers and ExceptionMappingProviders also provide further control over the application components, in terms of providing an application context (such as a Jaxbcontext instance) and mapping runtime exceptions to HTTP requests. Annotations are defined to control the injection of method parameters and class members, and they provide valuable contextual information to the application throughout the run-time process. Overall, Jax-rs is bound to be a simple, portable, and comprehensive API for the development of RESTful Java-based services.

Original address: http://www.ibm.com/developerworks/cn/web/wa-jaxrs/index.html

Creating RESTful Web Services with Java technology-reproduced

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.