The Java EE 6 Tutorial, Volume I

Part III Web Services

Part Three explores web services.

Chapter 11 Introduction to Web Services

This section of the tutorial discusses Java EE 6 web services technologies. For this book, these technologies include Java API for XML Web Services (JAX-WS) and Java API for RESTful Web Services (JAX-RS).

What Are Web Services?

Web services are client and server applications that communicate over the World Wide Web's (WWW) HyperText Transfer Protocol (HTTP) protocol.

As described by the World Wide Web Consortium (W3C,) web services provide a standard means of interoperating between different software applications, running on a variety of platforms and frameworks. Web services are characterized by their great interoperability and extensibility, as well as their machine-processable descriptions thanks to the use of XML. They can be combined in a loosely coupled way to achieve complex operations. Programs providing simple services can interact with each other to deliver sophisticated added-value services.

Types of Web Services

On the conceptual level, a service is a software component provided through a network-accessible endpoint. The service consumer and provider use messages to exchange invocation request and response information in the form of self-containing documents that make very few assumptions about the technological capabilities of the receiver.

On a technical level, web services can be implemented in different ways. The two types of web services discussed in this section can be distinguished as “Big” web services and “RESTful” web services.

Deciding Which Type of Web Service to Use

Basically, you would want to use RESTful web services for integration over the Web and use Big web services in enterprise application integration scenarios that have advanced QoS requirements. This topic is discussed in more detail in the following sections.


Note –

For an article that provides more in-depth analysis of this issue, see RESTful Web Services vs. “Big” Web Services: Making the Right Architectural Decision by Cesare Pautasso, Olaf Zimmermann, and Frank Leymann from the WWW '08: Proceedings of the 17th International Conference on the World Wide Web (2008), pp. 805-814.


When Should I Use JAX-WS?

JAX-WS addresses advanced quality of service (QoS) requirements commonly occurring in enterprise computing. When compared to JAX-RS, JAX-WS makes it easier to support the WS-* set of protocols (which provide standards for security and reliability, among other things) and interoperate with other WS-* conforming clients and servers.

When Should I Use JAX-RS?

When compared with JAX-WS, JAX-RS makes it easier to write applications for the web that apply some or all of the constraints of the REST style to induce desirable properties in the application like loose coupling (evolving the server is easier without breaking existing clients), scalability (start small and grow), and architectural simplicity (use off-the-shelf components like proxies, HTTP routers, or others). You would choose to use JAX-RS for your web application because it is easier for many types of clients to consume RESTful web services while enabling the server side to evolve and scale. Clients can choose to consume some or all aspects of the service and mash it up with other web-based services.

Chapter 12 Building Web Services with JAX-WS

JAX-WS stands for Java API for XML Web Services. JAX-WS is a technology for building web services and clients that communicate using XML. JAX-WS allows developers to write message-oriented as well as RPC-oriented web services.

In JAX-WS, a web service operation invocation is represented by an XML-based protocol such as SOAP. The SOAP specification defines the envelope structure, encoding rules, and conventions for representing web service invocations and responses. These calls and responses are transmitted as SOAP messages (XML files) over HTTP.

Although SOAP messages are complex, the JAX-WS API hides this complexity from the application developer. On the server side, the developer specifies the web service operations by defining methods in an interface written in the Java programming language. The developer also codes one or more classes that implement those methods. Client programs are also easy to code. A client creates a proxy (a local object representing the service) and then simply invokes methods on the proxy. With JAX-WS, the developer does not generate or parse SOAP messages. It is the JAX-WS runtime system that converts the API calls and responses to and from SOAP messages.

With JAX-WS, clients and web services have a big advantage: the platform independence of the Java programming language. In addition, JAX-WS is not restrictive: a JAX-WS client can access a web service that is not running on the Java platform, and vice versa. This flexibility is possible because JAX-WS uses technologies defined by the World Wide Web Consortium (W3C): HTTP, SOAP, and the Web Service Description Language (WSDL). WSDL specifies an XML format for describing a service as a set of endpoints operating on messages.

Setting the Port

Several files in the JAX-WS examples depend on the port that you specified when you installed the Enterprise Server. The tutorial examples assume that the server runs on the default port, 8080. If you have changed the port, you must update the port number in the following file before building and running the JAX-WS examples:


tut-install/examples/jaxws/simpleclient/src/java/simpleclient/HelloClient.java

Creating a Simple Web Service and Client with JAX-WS

This section shows how to build and deploy a simple web service and client. The source code for the service is in tut-install/examples/jaxws/helloservice/ and the client is in tut-install/examples/jaxws/simpleclient/.

Figure 12–1 illustrates how JAX-WS technology manages communication between a web service and client.

Figure 12–1 Communication between a JAX-WS Web Service and a Client

Diagram showing a client and web service communicating
through a SOAP message.

The starting point for developing a JAX-WS web service is a Java class annotated with the javax.jws.WebService annotation. The @WebService annotation defines the class as a web service endpoint.

A service endpoint interface or service endpoint implementation (SEI) is a Java interface or class, respectively, that declares the methods that a client can invoke on the service. An interface is not required when building a JAX-WS endpoint. The web service implementation class implicitly defines an SEI.

You may specify an explicit interface by adding the endpointInterface element to the @WebService annotation in the implementation class. You must then provide an interface that defines the public methods made available in the endpoint implementation class.

You use the endpoint implementation class and the wsgen tool to generate the web service artifacts that connect a web service client to the JAX-WS runtime. For reference documentation on wsgen, see the Sun GlassFish Enterprise Server v3 Reference Manual.

Together, the wsgen tool and the Enterprise Server provide the Enterprise Server’s implementation of JAX-WS.

    These are the basic steps for creating the web service and client:

  1. Code the implementation class.

  2. Compile the implementation class.

  3. Use wsgen to generate the artifacts required to deploy the service.

  4. Package the files into a WAR file.

  5. Deploy the WAR file. The web service artifacts (which are used to communicate with clients) are generated by the Enterprise Server during deployment.

  6. Code the client class.

  7. Use wsimport to generate and compile the web service artifacts needed to connect to the service.

  8. Compile the client class.

  9. Run the client.

The sections that follow cover these steps in greater detail.

Requirements of a JAX-WS Endpoint

JAX-WS endpoints must follow these requirements:

Coding the Service Endpoint Implementation Class

In this example, the implementation class, Hello, is annotated as a web service endpoint using the @WebService annotation. Hello declares a single method named sayHello, annotated with the @WebMethod annotation. @WebMethod exposes the annotated method to web service clients. sayHello returns a greeting to the client, using the name passed to sayHello to compose the greeting. The implementation class also must define a default, public, no-argument constructor.

package helloservice.endpoint;

import javax.jws.WebService;

@WebService
public class Hello {
    private String message = new String("Hello, ");

    public void Hello() {}

    @WebMethod
    public String sayHello(String name) {
        return message + name + ".";
    }
}

Building, Packaging, and Deploying the Service

You can build, package, and deploy the helloservice application using either NetBeans IDE or ant.

Building, Packaging, and Deploying the Service Using NetBeans IDE

Follow these instructions to build, package, and deploy the helloservice example to your Application Server instance using the NetBeans IDE IDE.

  1. In NetBeans IDE, select File->Open Project.

  2. In the Open Project dialog, navigate to tut-install/examples/jaxws/.

  3. Select the helloservice folder.

  4. Select the Open as Main Project check box.

  5. Click Open Project.

  6. In the Projects tab, right-click the helloservice project and select Undeploy and Deploy.

This builds and packages to application into helloservice.war, located in tut-install/examples/jaxws/helloservice/dist/, and deploys this WAR file to your Application Server instance.

Building, Packaging, and Deploying the Service Using Ant

To build and package helloservice using Ant, in a terminal window, go to the tut-install/examples/jaxws/helloservice/ directory and type the following:


ant

This command calls the default target, which builds and packages the application into an WAR file, helloservice.war, located in the dist directory.

    To deploy the helloservice example, follow these steps:

  1. In a terminal window, go to tut-install/examples/jaxws/helloservice/.

  2. Make sure the Enterprise Server is started.

  3. Run ant deploy.

You can view the WSDL file of the deployed service by requesting the URL http://localhost:8080/helloservice/hello?WSDL in a web browser. Now you are ready to create a client that accesses this service.

Undeploying the Service

At this point in the tutorial, do not undeploy the service. When you are finished with this example, you can undeploy the service by typing this command:


ant undeploy

The all Task

As a convenience, the all task will build, package, and deploy the application. To do this, enter the following command:


ant all

Testing the Service without a Client

    The Application Server Admin Console allows you to test the methods of a web service endpoint. To test the sayHello method of HelloService, do the following:

  1. Open the Admin Console by typing the following URL in a web browser:


    http://localhost:4848/
  2. Enter the admin user name and password to log in to the Admin Console.

  3. Click Web Services in the left pane of the Admin Console.

  4. Click Hello.

  5. Click Test.

  6. Under Methods, enter a name as the parameter to the sayHello method.

  7. Click the sayHello button.

    This will take you to the sayHello Method invocation page.

  8. Under Method returned, you’ll see the response from the endpoint.

A Simple JAX-WS Client

HelloClient is a standalone Java program that accesses the sayHello method of HelloService. It makes this call through a port, a local object that acts as a proxy for the remote service. The port is created at development time by the wsimport tool, which generates JAX-WS portable artifacts based on a WSDL file.

Coding the Client

    When invoking the remote methods on the port, the client performs these steps:

  1. Uses the generated helloservice.endpoint.HelloService class which represents the service at the URI of the deployed service’s WSDL file.

    HelloService service = new HelloService();
  2. Retrieves a proxy to the service, also known as a port, by invoking getHelloPort on the service.

    Hello port = service.getHelloPort();

    The port implements the SEI defined by the service.

  3. Invokes the port’s sayHello method, passing to the service a name.

    String response = port.sayHello(name);

Here is the full source of HelloClient, which is located in the tut-install/examples/jaxws/simpleclient/src/java/ directory.

package simpleclient;

import javax.xml.ws.WebServiceRef;
import helloservice.endpoint.HelloService;
import helloservice.endpoint.Hello;

public class HelloClient {

    public static void main(String[] args) {
        try {
            HelloClient client = new HelloClient();
            client.doTest(args);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public void doTest(String[] args) {
        try {
            System.out.println("Retrieving the port from
                     the following service: " + service);
				 HelloService service = new HelloService();
            Hello port = service.getHelloPort();
            System.out.println("Invoking the sayHello operation
                     on the port.");

            String name;
            if (args.length > 0) {
                name = args[0];
            } else {
                name = "No Name";
            }

            String response = port.sayHello(name);
            System.out.println(response);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

Building and Running the Client

You can build and run the simpleclient application using either NetBeans IDE or ant. To build the client, you must first have deployed helloservice, as described in Building, Packaging, and Deploying the Service.

Building and Running the Client in NetBeans IDE

    Do the following to build and run simpleclient:

  1. In NetBeans IDE, select File->Open Project.

  2. In the Open Project dialog, navigate to tut-install/examples/jaxws/.

  3. Select the simpleclient folder.

  4. Select the Open as Main Project check box.

  5. Click Open Project.

  6. In the Projects tab, right-click the simpleclient project and select Run.

You will see the output of the application client in the Output pane.

Building and Running the Client Using Ant

In a terminal navigate to tut-install/examples/jaxws/simpleclient/ and type the following command:


ant

This command calls the default target, which builds and packages the application into a JAR file, simpleclient.jar, located in the dist directory.

The run the client, type the following command:


ant run

Types Supported by JAX-WS

JAX-WS delegates the mapping of Java programming language types to and from XML definitions to JAXB. Application developers don’t need to know the details of these mappings, but they should be aware that not every class in the Java language can be used as a method parameter or return type in JAX-WS. For information on which types are supported by JAXB, see JAXB default data type bindings.

Web Services Interoperability and JAX-WS

JAX-WS 2.0 supports the Web Services Interoperability (WS-I) Basic Profile Version 1.1. The WS-I Basic Profile is a document that clarifies the SOAP 1.1 and WSDL 1.1 specifications to promote SOAP interoperability. For links related to WS-I, see Further Information about JAX-WS.

To support WS-I Basic Profile Version 1.1, the JAX-WS runtime supports doc/literal and rpc/literal encodings for services, static ports, dynamic proxies, and DII.

Further Information about JAX-WS

For more information about JAX-WS and related technologies, see:

Chapter 13 Building RESTful Web Services with JAX-RS and Jersey

PUThis chapter describes the REST architecture, RESTful web services, and Sun's reference implementation for JAX-RS (JavaTM API for RESTful Web Services, JSR-311), which is referred to as Jersey.

What are RESTful Web Services?

RESTful web services are services that are built to work best on the web. Representational State Transfer (REST) is an architectural style that specifies constraints, such as the uniform interface, that if applied to a web service induce desirable properties, such as performance, scalability, and modifiability, that enable services to work best on the Web. In the REST architectural style, data and functionality are considered resources, and these resources are accessed using Uniform Resource Identifiers (URIs), typically links on the web. The resources are acted upon by using a set of simple, well-defined operations. The REST architectural style constrains an architecture to a client-server architecture, and is designed to use a stateless communication protocol, typically HTTP. In the REST architecture style, clients and servers exchange representations of resources using a standardized interface and protocol. These principles encourages RESTful applications to be simple, lightweight, and have high performance.

A paper that expands on the basic principles of REST technology can be found at http://www2008.org/papers/pdf/p805-pautassoA.pdf.

Where Does Jersey Fit In?

Jersey is Sun's production quality reference implementation for JSR 311: JAX-RS: The Java API for RESTful Web Services. Jersey implements support for the annotations defined in JSR-311, making it easy for developers to build RESTful web services with Java and the Java JVM. Jersey also adds additional features not specified by the JSR.

The latest version of the JAX-RS API's can be viewed at https://jsr311.dev.java.net/nonav/javadoc/index.html

If you are developing with Enterprise Server v3, you can install the Jersey samples and documentation using the Update Tool. Instructions for using the Update Tool can be found in the section Java EE 6 Tutorial Component.

Creating a RESTful Root Resource Class

Root resource classes are POJOs (Plain Old Java Objects) that are either annotated with@Path or have at least one method annotated with @Path or a request method designator such as @GET, @PUT, @POST, or @DELETE. Resource methods are methods of a resource class annotated with a request method designator. This section describes how to use Jersey to annotate Java objects to create RESTful web services.

Developing RESTful Web Services with JAX-RS and Jersey

The JAX-RS API for developing RESTful web services is a Java programming language API designed to make it easy to develop applications that use the REST architecture.

The JAX-RS API uses Java programming language annotations to simplify the development of RESTful web services. Developers decorate Java programming language class files with HTTP-specific annotations to define resources and the actions that can be performed on those resources. Jersey annotations are runtime annotations, therefore, runtime reflection will generate the helper classes and artifacts for the resource, and then the collection of classes and artifacts will be built into a web application archive (WAR). The resources are exposed to clients by deploying the WAR to a Java EE or web server.

Here is a listing of some of the Java programming annotations that are defined by JAX-RS, with a brief description of how each is used. Further information on the JAX-RS API's can be viewed at https://jsr311.dev.java.net/nonav/javadoc/index.html.

Table 13–1 Summary of Jersey Annotations

Annotation 

Description 

@Path 

The @Path annotation's value is a relative URI path indicating where the Java class will be hosted, for example, /helloworld. You can also embed variables in the URIs to make a URI path template. For example, you could ask for the name of a user, and pass it to the application as a variable in the URI, like this, /helloworld/{username}.

@GET 

The @GET annotation is a request method designator and corresponds to the similarly named HTTP method. The Java method annotated with this request method designator will process HTTP GET requests. The behavior of a resource is determined by the HTTP method to which the resource is responding.

@POST 

The @POST annotation is a request method designator and corresponds to the similarly named HTTP method. The Java method annotated with this request method designator will process HTTP POST requests. The behavior of a resource is determined by the HTTP method to which the resource is responding.

@PUT 

The @PUT annotation is a request method designator and corresponds to the similarly named HTTP method. The Java method annotated with this request method designator will process HTTP PUT requests. The behavior of a resource is determined by the HTTP method to which the resource is responding.

@DELETE 

The @DELETE annotation is a request method designator and corresponds to the similarly named HTTP method. The Java method annotated with this request method designator will process HTTP DELETE requests. The behavior of a resource is determined by the HTTP method to which the resource is responding.

@HEAD 

The @HEAD annotation is a request method designator and corresponds to the similarly named HTTP method. The Java method annotated with this request method designator will process HTTP HEAD requests. The behavior of a resource is determined by the HTTP method to which the resource is responding.

@PathParam 

The @PathParam annotation is a type of parameter that you can extract for use in your resource class. URI path parameters are extracted from the request URI, and the parameter names correspond to the URI path template variable names specified in the @Path class-level annotation.

@QueryParam 

The @QueryParam annotation is a type of parameter that you can extract for use in your resource class. Query parameters are extracted from the request URI query parameters.

@Consumes 

The @Consumes annotation is used to specify the MIME media types of representations a resource can consume that were sent by the client.

@Produces 

The @Produces annotation is used to specify the MIME media types of representations a resource can produce and send back to the client, for example, "text/plain".

@Provider 

The @Provider annotation is used for anything that is of interest to the JAX-RS runtime, such as MessageBodyReader and MessageBodyWriter. For HTTP requests, the MessageBodyReader is used to map an HTTP request entity body to method parameters. On the response side, a return value is mapped to an HTTP response entity body using a MessageBodyWriter. If the application needs to supply additional metadata, such as HTTP headers or a different status code, a method can return a Response that wraps the entity, and which can be built using Response.ResponseBuilder.

Overview of a Jersey-Annotated Application

The following code sample is a very simple example of a root resource class using JAX-RS annotations. The sample shown here is from the samples that ship with Jersey, and which can be found in the following directory of that installation: jersey/samples/helloworld/src/main/java/com/sun/jersey/samples/helloworld/resources/HelloWorldResource.java.

package com.sun.jersey.samples.helloworld.resources;

import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;

// The Java class will be hosted at the URI path "/helloworld"
@Path("/helloworld")
public class HelloWorldResource {
    
    // The Java method will process HTTP GET requests
    @GET
    // The Java method will produce content identified by the MIME Media
    // type "text/plain"
    @Produces("text/plain")
    public String getClichedMessage() {
        // Return some cliched textual content
        return "Hello World";
    }
}

The following sections describe the annotations used in this example.

The @Path Annotation and URI Path Templates

The @Path annotation identifies the URI path template to which the resource responds, and is specified at the class level of a resource. The @Path annotation's value is a partial URI path template relative to the base URI of the server on which the resource is deployed, the context root of the WAR, and the URL pattern to which the Jersey helper servlet responds.

URI path templates are URIs with variables embedded within the URI syntax. These variables are substituted at runtime in order for a resource to respond to a request based on the substituted URI. Variables are denoted by curly braces. For example, look at the following @Path annotation:

@Path("/users/{username}")

In this type of example, a user will be prompted to enter their name, and then a Jersey web service configured to respond to requests to this URI path template will respond. For example, if the user entered their user name as Galileo, the web service will respond to the following URL:

http://example.com/users/Galileo

To obtain the value of the username variable, the @PathParamannotation may be used on the method parameter of a request method, as shown in the following code example.

@Path("/users/{username}")
public class UserResource {

    @GET
    @Produces("text/xml")
    public String getUser(@PathParam("username") String userName) {
        ...
    }
}

If it is required that a user name must only consist of lower and upper case numeric characters, it is possible to declare a particular regular expression that will override the default regular expression, "[^/]+?". The following example shows how this could be used with the @Path annotation.

@Path("users/{username: [a-zA-Z][a-zA-Z_0-9]}")

In this type of example the username variable will only match user names that begin with one upper or lower case letter and zero or more alpha numeric characters and the underscore character. If a user name does not match that template, then a 404 (Not Found) response will occur.

An @Path value may or may not begin with a forward slash (/), it makes no difference. Likewise, by default, an @Path value may or may not end in a forward lash (/), it makes no difference, and thus request URLs that end or do not end with a forward slash will both be matched. However, Jersey has a redirection mechanism, which, if enabled, automatically performs redirection to a request URL ending in a / if a request URL does not end in a / and the matching @Path does end in a /.

More on URI Path Template Variables

A URI path template has one or more variables, with each variable name surrounded by curly braces, { to begin the variable name and } to end it. In the example above, username is the variable name. At runtime, a resource configured to respond to the above URI path template will attempt to process the URI data that corresponds to the location of {username} in the URI as the variable data for username.

For example, if you want to deploy a resource that responds to the URI path template http://example.com/myContextRoot/jerseybeans/{name1}/{name2}/, you must deploy the WAR to a Java EE server that responds to requests to the http://example.com/myContextRoot URI, and then decorate your resource with the following @Path annotation:

@Path("/{name1}/{name2}/")
public class SomeResource {
	...
}

In this example, the URL pattern for the Jersey helper servlet, specified in web.xml, is the default:

<servlet-mapping>
	  <servlet-name>My Jersey Bean Resource</servlet-name>
	  <url-pattern>/jerseybeans/*</url-pattern>
</servlet-mapping>

A variable name can be used more than once in the URI path template.

If a character in the value of a variable would conflict with the reserved characters of a URI, the conflicting character should be substituted with percent encoding. For example, spaces in the value of a variable should be substituted with %20.

Be careful when defining URI path templates that the resulting URI after substitution is valid.

The following table lists some examples of URI path template variables and how the URIs are resolved after substitution. The following variable names and values are used in the examples:


Note –

The value of the name3 variable is an empty string.


Table 13–2 Examples of URI path templates

URI Path Template 

URI After Substitution 

http://example.com/{name1}/{name2}/

http://example.com/jay/gatsby/

http://example.com/{question}/

{question}/{question}/

http://example.com/why/why/why/

http://example.com/maps/{location}

http://example.com/maps/Main%20Street

http://example.com/{name3}/home/

http://example.com//home/

Responding to HTTP Resources

The behavior of a resource is determined by the HTTP methods (typically, GET, POST, PUT, DELETE) to which the resource is responding.

The Request Method Designator Annotations

A request method designatorannotations are runtime annotations, defined by JAX-RS, and which correspond to the similarly named HTTP methods. Within a resource class file, HTTP methods are mapped to Java programming language methods using the request method designator annotations. The behavior of a resource is determined by which of the HTTP methods the resource is responding to. Jersey defines a set of request method designators for the common HTTP methods: @GET, @POST, @PUT, @DELETE, @HEAD, but you can create your own custom request method designators. Creating custom request method designators is outside the scope of this document.

The following example is an extract from the storage service sample that shows the use of the PUTmethod to create or update a storage container.

@PUT
public Response putContainer() {
    System.out.println("PUT CONTAINER " + container);

    URI uri =  uriInfo.getAbsolutePath();
    Container c = new Container(container, uri.toString());

    Response r;
    if (!MemoryStore.MS.hasContainer(c)) {
        r = Response.created(uri).build();
    } else {
        r = Response.noContent().build();
    }

    MemoryStore.MS.createContainer(c);
    return r;
}

By default the JAX-RS runtime will automatically support the methods HEAD and OPTIONS if not explicitly implemented. For HEAD, the runtime will invoke the implemented GET method (if present) and ignore the response entity (if set). For OPTIONS, the Allow response header will be set to the set of HTTP methods support by the resource. In addition Jersey will return a WADL document describing the resource.

Methods decorated with request method designators must return void, a Java programming language type, or a javax.ws.rs.core.Response object. Multiple parameters may be extracted from the URI using the PathParam or QueryParam annotations as described in Extracting Request Parameters. Conversion between Java types and an entity body is the responsibility of an entity provider, such as MessageBodyReader or MessageBodyWriter. Methods that need to provide additional metadata with a response should return an instance of Response. The ResponseBuilder class provides a convenient way to create a Response instance using a builder pattern. The HTTP PUT and POST methods expect an HTTP request body, so you should use a MessageBodyReader for methods that respond to PUT and POST requests.

As PUT and POST can post be used to create or update, here is a bit more information on when you'd use each:

Using Entity Providers to Map HTTP Response and Request Entity Bodies

Entity providers supply mapping services between representations and their associated Java types. There are two types of entity providers: MessageBodyReader and MessageBodyWriter. For HTTP requests, the MessageBodyReader is used to map an HTTP request entity body to method parameters. On the response side, a return value is mapped to an HTTP response entity body using a MessageBodyWriter. If the application needs to supply additional metadata, such as HTTP headers or a different status code, a method can return a Response that wraps the entity, and which can be built using Response.ResponseBuilder.

The following list contains the standard types that are supported automatically for entities. You only need to write an entity provider if you are not choosing one of the following, standard types.

The following example shows how to use MessageBodyReader with the @Consumes and @Provider annotations:

@Consumes("application/x-www-form-urlencoded")
@Provider
public class FormReader implements MessageBodyReader<NameValuePair> {

The following example shows how to use MessageBodyWriter with the @Produces and @Provider annotations:

@Produces("text/html")
@Provider
public class FormWriter implements MessageBodyWriter<Hashtable<String, String>> {

The following example shows how to use ResponseBuilder:

    @GET
    public Response getItem() {
        System.out.println("GET ITEM " + container + " " + item);
        
        Item i = MemoryStore.MS.getItem(container, item);
        if (i == null)
            throw new NotFoundException("Item not found");
        Date lastModified = i.getLastModified().getTime();
        EntityTag et = new EntityTag(i.getDigest());
        ResponseBuilder rb = request.evaluatePreconditions(lastModified, et);
        if (rb != null)
            return rb.build();
            
        byte[] b = MemoryStore.MS.getItemData(container, item);
        return Response.ok(b, i.getMimeType()).
                lastModified(lastModified).tag(et).build();
    }    

Using @Consumes and @Produces to Customize Requests and Responses

The information sent to a resource and then passed back to the client is specified as a MIME media type in the headers of an HTTP request or response. You can specify which MIME media types of representations a resource can respond to or produce by using the javax.ws.rs.Consumes and javax.ws.rs.Produces annotations.

By default, a resource class can respond to and produce all MIME media types of representations specified in the HTTP request and response headers.

The @Produces Annotation

The @Produces annotation is used to specify the MIME media types or representations a resource can produce and send back to the client. If @Produces is applied at the class level, all the methods in a resource can produce the specified MIME types by default. If it is applied at the method level, it overrides any @Produces annotations applied at the class level.

If no methods in a resource are able to produce the MIME type in a client request, the Jersey runtime sends back an HTTP “406 Not Acceptable” error.

The value of @Produces is an array of String of MIME types. For example:

@Produces({"image/jpeg,image/png"})

The following example shows how to apply @Produces at both the class and method levels:

@Path("/myResource")
@Produces("text/plain")
public class SomeResource {
	@GET
	public String doGetAsPlainText() {
		...
	}

	@GET
	@Produces("text/html")
	public String doGetAsHtml() {
		...
	}
}

The doGetAsPlainText method defaults to the MIME media type of the @Produces annotation at the class level. The doGetAsHtml method's @Produces annotation overrides the class-level @Produces setting, and specifies that the method can produce HTML rather than plain text.

If a resource class is capable of producing more that one MIME media type, the resource method chosen will correspond to the most acceptable media type as declared by the client. More specifically, the Accept header of the HTTP request declared what is most acceptable. For example if the Accept header is Accept: text/plain, the doGetAsPlainText method will be invoked. Alternatively if the Accept header is Accept: text/plain;q=0.9, text/html, which declares that the client can accept media types of text/plain and text/html, but prefers the latter, then the doGetAsHtml method will be invoked.

More than one media type may be declared in the same @Produces declaration. The following code example shows how this is done.

@Produces({"application/xml", "application/json"})
public String doGetAsXmlOrJson() {
	...
}

The doGetAsXmlOrJson method will get invoked if either of the media types application/xml and application/json are acceptable. If both are equally acceptable, then the former will be chosen because it occurs first. The examples above refer explicitly to MIME media types for clarity. It is possible to refer to constant values, which may reduce typographical errors. For more information, see the constant field values of MediaType.

The @Consumes Annotation

The @Consumes annotation is used to specify which MIME media types of representations a resource can accept, or consume, from the client. If @Consumes is applied at the class level, all the response methods accept the specified MIME types by default. If @Consumes is applied at the method level, it overrides any @Consumes annotations applied at the class level.

If a resource is unable to consume the MIME type of a client request, the Jersey runtime sends back an HTTP “415 Unsupported Media Type” error.

The value of @Consumes is an array of String of acceptable MIME types. For example:

@Consumes({"text/plain,text/html"})

The following example shows how to apply @Consumes at both the class and method levels:

@Path("/myResource")
@Consumes("multipart/related")
public class SomeResource {
	@POST
	public String doPost(MimeMultipart mimeMultipartData) {
		...
	}

	@POST
	@Consumes("application/x-www-form-urlencoded")
	public String doPost2(FormURLEncodedProperties formData) {
		...
	}
}

The doPost method defaults to the MIME media type of the @Consumes annotation at the class level. The doPost2 method overrides the class level @Consumes annotation to specify that it can accept URL-encoded form data.

If no resource methods can respond to the requested MIME type, an HTTP 415 error (Unsupported Media Type) is returned to the client.

The HelloWorld example discussed previously in this section can be modified to set the cliched message using @Consumes, as shown in the following code example.

@POST
@Consumes("text/plain")
public void postClichedMessage(String message) {
    // Store the message
}

In this example, the Java method will consume representations identified by the MIME media type text/plain. Notice that the resource method returns void. This means no representation is returned and response with a status code of HTTP 204 (No Content) will be returned.

Extracting Request Parameters

Parameters of a resource method may be annotated with parameter-based annotations to extract information from a request. A previous example presented the use of the @PathParam parameter to extract a path parameter from the path component of the request URL that matched the path declared in @Path. There are six types of parameters you can extract for use in your resource class: query parameters, URI path parameters, form parameters, cookie parameters, header parameters, and matrix parameters.

Query parameters are extracted from the request URI query parameters, and are specified by using the javax.ws.rs.QueryParam annotation in the method parameter arguments. The following example (from the sparklines sample application) demonstrates using @QueryParam to extract query parameters from the Query component of the request URL.

@Path("smooth")
@GET
public Response smooth(
        @DefaultValue("2") @QueryParam("step") int step,
        @DefaultValue("true") @QueryParam("min-m") boolean hasMin,
        @DefaultValue("true") @QueryParam("max-m") boolean hasMax,
        @DefaultValue("true") @QueryParam("last-m") boolean hasLast,           
        @DefaultValue("blue") @QueryParam("min-color") ColorParam minColor,
        @DefaultValue("green") @QueryParam("max-color") ColorParam maxColor,
        @DefaultValue("red") @QueryParam("last-color") ColorParam lastColor
        ) { ... }

If a query parameter "step" exists in the query component of the request URI, then the "step" value will be extracted and parsed as a 32–bit signed integer and assigned to the step method parameter. If "step" does not exist, then a default value of 2, as declared in the @DefaultValue annotation, will be assigned to the step method parameter. If the "step" value cannot be parsed as a 32–bit signed integer, then an HTTP 400 (Client Error) response is returned.

User-defined Java types such as ColorParam may be used. The following code example shows how to implement this.

public class ColorParam extends Color {
    public ColorParam(String s) {
        super(getRGB(s));
    }

    private static int getRGB(String s) {
        if (s.charAt(0) == '#') {
            try {
                Color c = Color.decode("0x" + s.substring(1));
                return c.getRGB();
            } catch (NumberFormatException e) {
                throw new WebApplicationException(400);
            }
        } else {
            try {
                Field f = Color.class.getField(s);
                return ((Color)f.get(null)).getRGB();
            } catch (Exception e) {
                throw new WebApplicationException(400);
            }
        }
    }
}

@QueryParam and @PathParam can only be used on the following Java types:

If @DefaultValue is not used in conjunction with @QueryParam, and the query parameter is not present in the request, then value will be an empty collection for List, Set, or SortedSet; null for other object types; and the Java-defined default for primitive types.

URI path parameters are extracted from the request URI, and the parameter names correspond to the URI path template variable names specified in the @Path class-level annotation. URI parameters are specified using the javax.ws.rs.PathParam annotation in the method parameter arguments. The following example shows how to use @Path variables and the @PathParam annotation in a method:

@Path("/{userName}")
public class MyResourceBean {
	...
	@GET
	public String printUserName(@PathParam("userName") String userId) {
		...
	}
}

In the above snippet, the URI path template variable name userName is specified as a parameter to the printUserName method. The @PathParam annotation is set to the variable name userName. At runtime, before printUserName is called, the value of userName is extracted from the URI and cast to a String. The resulting String is then available to the method as the userId variable.

If the URI path template variable cannot be cast to the specified type, the Jersey runtime returns an HTTP 400 Bad Request error to the client. If the @PathParam annotation cannot be cast to the specified type, the Jersey runtime returns an HTTP 404 Not Found error to the client.

The @PathParam parameter and the other parameter-based annotations, @MatrixParam, @HeaderParam, @CookieParam, and @FormParam obey the same rules as @QueryParam.

Cookie parameters (indicated by decorating the parameter with javax.ws.rs.CookieParam) extract information from the cookies declared in cookie-related HTTP headers. Header parameters (indicated by decorating the parameter with javax.ws.rs.HeaderParam) extracts information from the HTTP headers. Matrix parameters (indicated by decorating the parameter with javax.ws.rs.MatrixParam) extracts information from URL path segments. These parameters are beyond the scope of this tutorial.

Form parameters (indicated by decorating the parameter with javax.ws.rs.FormParam) extract information from a request representation that is of the MIME media type application/x-www-form-urlencoded and conforms to the encoding specified by HTML forms, as described here. This parameter is very useful for extracting information that is POSTed by HTML forms. The following example extracts the form parameter named "name" from the POSTed form data.

@POST
@Consumes("application/x-www-form-urlencoded")
public void post(@FormParam("name") String name) {
    // Store the message
}

If it is necessary to obtain a general map of parameter names to values, use code such as that shown in the following example , for query and path parameters.

@GET
public String get(@Context UriInfo ui) {
    MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
    MultivaluedMap<String, String> pathParams = ui.getPathParameters();
}

Or code such as the following for header and cookie parameters:

@GET
public String get(@Context HttpHeaders hh) {
    MultivaluedMap<String, String> headerParams = ui.getRequestHeaders();
    Map<String, Cookie> pathParams = ui.getCookies();
}

In general @Context can be used to obtain contextual Java types related to the request or response.

For form parameters it is possible to do the following:

@POST
@Consumes("application/x-www-form-urlencoded")
public void post(MultivaluedMap<String, String> formParams) {
    // Store the message
}

Overview of JAX-RS and Jersey: Further Information

The following documents contain information that you might find useful when creating applications using Jersey and JAX-RS.

Example Applications for JAX-RS and Jersey

This section provides an introduction to creating, deploying, and running your own Jersey applications. This section demonstrates the steps that you would take to create, build, deploy, and test a very simple web application that is annotated with Jersey.

Another way that you could learn more about deploying and running Jersey applications is to review the many sample applications that ship with Jersey. These samples are installed into the as-install/jersey/samples directory when the Jersey Documentation and Samples are installed onto the Enterprise Server using the Update Tool. The process of installing from the Update Tool is described in Java EE 6 Tutorial Component. There is a README.html file for each sample that describes the sample and describes how to deploy and test the sample. These samples also include a Project Object Model file, pom.xml, that is used by Maven to build the project. The sample applications that ship with Jersey require Maven to run. The sample applications included with the tutorial will run using Ant.

Creating a RESTful Web Service

This section discusses two ways that you can create a RESTful web service. If you choose to use NetBeans IDE to create a RESTful web service, the IDE generates a skeleton where you simply need to implement the appropriate methods. If you choose not to use an IDE, try using one of the example applications that ship with Jersey as a template to modify.

Procedure Creating a RESTful Web Service Using NetBeans IDE

This section describes, using a very simple example, how to create a Jersey-annotated web application from NetBeans IDE.

  1. In NetBeans IDE, create a simple web application. This example creates a very simple “Hello, World” web application.

    1. Open NetBeans IDE.

    2. Select File->New Project.

    3. From Categories, select Java Web. From Projects, select Web Application. Click Next.


      Note –

      For this step, you could also create a RESTful web service in a Maven web project by selecting Maven as the category and Maven Web Project as the project. The remaining steps would be the same.


    4. Enter a project name, HelloWorldApplication, click Next.

    5. Make sure the Server is Sun GlassFish v3 (or similar wording.)

    6. Click Finish. You may be prompted for your server Administrator User Name and Password. If so, enter this information.

  2. The project will be created. The file index.jsp will display in the Source pane.

  3. Right-click the project and select New, then select RESTful Web Services from Patterns.

    1. Select Simple Root Resource. Click Next.

    2. Enter a Resource Package name, like helloWorld.

    3. Enter helloworld in the Path field. Enter HelloWorld in the Class Name field. For MIME Type select text/html.

    4. Click Finish.

    5. The REST Resources Configuration page displays. Select OK.

      A new resource, HelloWorld.java, is added to the project and displays in the Source pane. This file provides a template for creating a RESTful web service.

  4. In HelloWorld.java, find the getHtml() method. Replace the //TODO comment and the exception with the following text, so that the finished product resembles the following method.


    Note –

    Because the MIME type that is produces is HTML, you can use HTML tags in your return statement.


    /**
         * Retrieves representation of an instance of helloWorld.HelloWorld
         * @return an instance of java.lang.String
         */
        @GET
        @Produces("text/html")
        public String getHtml() {
            return "<html><body><h1>Hello, World!!</body></h1></html>";
        }
    
        
  5. Test the web service. To do this, right-click the project node and click Test RESTful Web Services.

    This step will deploy the application and bring up a test client in the browser.

  6. When the test client displays, select the helloworld resource in the left pane, and click the Test button in the right pane.

    The words Hello, World!! will display in the Response window below.

  7. Deploy and Run the application.

    1. Set the Run Properties. To do this, right-click the project node, select Properties, and then select the Run category. Set the Relative URL to the location of the RESTful web service relative to the Context Path, which for this example is resources/helloworld.


      Tip –

      You can find the value for the Relative URL in the Test RESTful Web Services browser window. In the top of the right pane, after Resource, is the URL for the RESTful web service being tested. The part following the Context Path (http://localhost:8080/HelloWorldApp) is the Relative URL that needs to be entered here.

      If you don't set this property, by default the file index.jsp will display when the application is run. As this file also contains Hello World as its default value, you might not notice that your RESTful web service isn't running, so just be aware of this default and the need to set this property, or update index.jsp to provide a link to the RESTful web service.


    2. Right-click the project and select Deploy.

    3. Right-click the project and select Run.

      A browser window opens and displays the return value of Hello, World!!

See Also

For other sample applications that demonstrate deploying and running Jersey applications using NetBeans, read Example: Creating a Simple Hello World Application Using JAX-RS and Jersey and/or look at the tutorials on the NetBeans tutorial site, such as the one titled Getting Started with RESTful Web Services. This tutorial includes a section on creating a CRUD application from a database. Create, read, update and delete (CRUD) are the four basic functions of persistent storage and relational databases.

ProcedureCreating a RESTful Web Service From Examples

The easiest way to create and run an application without NetBeans IDE is to copy and edit one of the Jersey sample applications. These samples are installed into the as-install/jersey/samples directory when the Jersey Documentation and Samples are installed onto the Enterprise Server using the Update Tool. The process of installing from the Update Tool is described in Java EE 6 Tutorial Component. This task uses the simplest sample application, helloworld-webapp, to demonstrate one way you could go about creating your own application without NetBeans IDE.

Before You Begin

Before you can deploy the Jersey sample applications to GlassFish from the command line, you must have downloaded and installed Maven onto your system. You can install Maven from the Maven website at http://maven.apache.org.

  1. Copy the helloworld-webapp application to a new directory named helloworld2. You will find this application in the directory as-install/glassfish/jersey/samples/helloworld-webapp.

  2. Do a search for all directories named helloworld-webapp and rename them to helloworld2.

  3. Search again for all files containing the text helloworld-webapp and edit these files to replace this text with helloworld2.

  4. Using a text editor, open the file jersey/samples/helloworld2/src/main/java/com/sun/jersey/samples/helloworld/resources/HelloWorldResource.java.

  5. Modify the text that is returned by the resource to Hello World 2. Save and close the file.

  6. Use Maven to compile and deploy the application. For this sample application, it is deployed onto Grizzly. Enter the following command from the command line in the directory jersey/samples/helloworld2 to compile and deploy the application: mvn glassfish:run.

  7. Open a web browser, and enter the URL to which the application was deployed, which in this examples is http://localhost:8080/helloworld2/helloworld. Hello World 2 will display in the browser.

See Also

You can learn more about deploying and running Jersey applications by reviewing the many sample applications that ship with Jersey. There is a README.html file for each sample that describes the sample and describes how to deploy and test the sample, and there is a Project Object Model file, pom.xml, that is used by Maven to build the project. Find a project that is similar to one you are hoping to create and use it as a template to get you started.

An example that starts from scratch can be found here.

For questions regarding Jersey sample applications, visit the Jersey Community Wiki page, or send an email to the users mailing list, users@jersey.dev.java.net.

ProcedureCreating a RESTful Web Service From Maven Archetype

Although this tutorial does not present instructions on using Maven for creating applications as a general rule, because Project Jersey is built, assembled and installed using Maven, and all of its sample applications are Maven-based, this section provides an example that creates a skeleton Jersey application from a Maven archetype.

Before You Begin

This example requires that Maven be installed and configured to run from the command line on your system. Maven can be downloaded from http://maven.apache.org/.

  1. Start the Enterprise Server. For instructions on how to do this, read Starting and Stopping the Enterprise Server.

  2. After Maven is installed, run the following from the command line:

    mvn archetype:generate -DarchetypeCatalog=http://download.java.net/maven/2

    The archetype catalog will download. You will be prompted to select the type of archetype you want to create. As of the publication date of this tutorial, the following choices display in the command window. These options are likely to change, but are provided here to give you an idea of what they might look like.


    Choose archetype:
    1: http://download.java.net/maven/2/archetype-catalog.xml -> 
    jersey-quickstart-grizzly (Archetype for creating a RESTful web 
    application with Jersey and Grizzly)
    
    2: http://download.java.net/maven/2/archetype-catalog.xml -> 
    jersey-quickstart-webapp (Archetype for creating a Jersey based RESTful 
    web application with WAR packaging)
    
    3: http://download.java.net/maven/2/archetype-catalog.xml -> 
    jersey-quickstart-ejb (Archetype for creating a Jersey based RESTful EJB 
    application with WAR packaging)
    
    4: http://download.java.net/maven/2/archetype-catalog.xml -> 
    jsf2-simple-example-archetype (Simple JSF project with no non-JavaEE 
    dependencies)
  3. Select the appropriate option for the type of RESTful web service you would like to create.

    With the Grizzly-based archetype (selection 1), you will get a sample Java application, which you can run directly from Java without a need to deploy it to any container. The web application archetype (selection 2) enables you to build a WAR archive, which you could deploy onto any web Servlet container.

  4. Define a value for groupId, such as RESTHello.

  5. Define a value for artifactId, such as RESTHelloApp. This is the name of the web application as well as the directory in which the application is created.

  6. Define value for version: 1.0–SNAPSHOT. You can accept the default by not entering anything.

  7. Define value for package: groupId, such as restHello. This is the directory where the main Java files will be located, which is basedir/artifactId/src/main/java/package. If you used the example entries, this directory will be RESTHelloApp/src/main/java/restHello.

  8. Confirm properties configuration. Enter Y to confirm or N to cancel.

    Maven generates a new project containing a simple Hello World RESTful web service.

  9. Build and run your RESTful web service. First, change into the project directory, which is the artifactId, or RESTHelloApp if you used the example text.

    • For the Grizzly-based scenario (selection 1), build and run the web service on the Grizzy container using this command: mvn clean compile exec:java.

    • If you selected the WAR-based scenario (selection 2), build your WAR file using the command mvn clean package. Deploy the WAR file to your favorite Servlet container. To run it using the embedded version of GlassFish V3, use this command: mvn glassfish:run.

  10. Test the service in your browser.

    • Enter the following URL to run the Grizzly-based application (selection 1): http://localhost:9998/myresource. This is the location where it is published by default. The browser displays the text Got it!

    • Enter the following URL to run the WAR-based scenario (selection 2): http://localhost:8080/artifactId/webresources/myresource. If you used the example entries, enter http://localhost:8080/RESTHelloApp/webresources/myresource. This is the location where it is published by default. The browser displays the text Hi there!

      After starting the application using Grizzly, you should see output that looks similar to that in the example output, below:

      [INFO] ------------------------------------------------------------------------
      [INFO] Building RESTHelloApp
      [INFO]    task-segment: [clean, compile, exec:java]
      [INFO] ------------------------------------------------------------------------
      [INFO] [clean:clean]
      [INFO] [resources:resources]
      [INFO] Using default encoding to copy filtered resources.
      [INFO] [compiler:compile]
      [INFO] Compiling 2 source files to /export/home/japod/test/jaxrs-tutorial/
      			RESTHelloApp/target/classes
      [INFO] Preparing exec:java
      [INFO] No goals needed for project - skipping
      [INFO] [exec:java]
      Starting grizzly...
      Jersey app started with WADL available at http://localhost:9998/application.wadl
      Hit enter to stop it...

      After starting the application for the WAR-based scenario, you should see output that looks similar to that in the example output, below:

      [INFO] Building RESTHelloApp Jersey Webapp
      [INFO]    task-segment: [glassfish:run]
      [INFO] ------------------------------------------------------------------------
      [INFO] Preparing glassfish:run
      [INFO] [resources:resources]
      [INFO] Using default encoding to copy filtered resources.
      [INFO] snapshot org.glassfish:glassfish-parent:10.0-SNAPSHOT: checking for 
      			updates from 	glassfish-maven2-repository.dev.java.net
      [INFO] [compiler:compile]
      [INFO] Compiling 1 source file to /export/home/japod/test/jaxrs-tutorial/
      			RESTHelloApp/target/classes
      [INFO] [glassfish:run]
      Dec 8, 2009 1:20:34 AM com.sun.enterprise.v3.server.AppServerStartup run
      INFO: HK2 initialized in 479 ms
      Dec 8, 2009 1:20:34 AM com.sun.enterprise.v3.server.AppServerStartup run
      INFO: com.sun.enterprise.naming.impl.ServicesHookup@1342545 Init done in 486 ms
      Dec 8, 2009 1:20:34 AM com.sun.enterprise.v3.server.AppServerStartup run
      INFO: com.sun.enterprise.v3.server.Globals@6de609 Init done in 488 ms
      Dec 8, 2009 1:20:34 AM com.sun.enterprise.v3.server.AppServerStartup run
      INFO: com.sun.enterprise.v3.server.SystemTasks@e7e8eb Init done in 493 ms
      Dec 8, 2009 1:20:34 AM com.sun.enterprise.v3.server.AppServerStartup run
      INFO: com.sun.enterprise.v3.services.impl.HouseKeeper@1a6518 Init done in 503 ms
      Dec 8, 2009 1:20:34 AM com.sun.enterprise.v3.server.AppServerStartup run
      INFO: com.sun.enterprise.v3.services.impl.CmdLineParamProcessor@8390b0 
      			Init done in 506 ms
      JMXMP connector server URL = service:jmx:jmxmp://localhost:8888
      Dec 8, 2009 1:20:35 AM com.sun.enterprise.v3.services.impl.GrizzlyProxy start
      INFO: Listening on port 8080
      Dec 8, 2009 1:20:35 AM com.sun.enterprise.v3.server.AppServerStartup run
      INFO: com.sun.enterprise.v3.services.impl.GrizzlyService@59cbda startup 
      			done in 815 ms
      Dec 8, 2009 1:20:35 AM com.sun.enterprise.v3.services.impl.
      			ApplicationLoaderService postConstruct
      INFO: loader service postConstruct started at 1260231635181
      Dec 8, 2009 1:20:35 AM com.sun.enterprise.v3.server.AppServerStartup run
      INFO: Application Loader startup done in 883 ms
      Dec 8, 2009 1:20:35 AM com.sun.enterprise.v3.server.AppServerStartup run
      INFO: Glassfish v3 started in 883 ms
      Dec 8, 2009 1:20:38 AM com.sun.enterprise.web.WebModuleContextConfig 
      			authenticatorConfig
      SEVERE: webModuleContextConfig.missingRealm
      Dec 8, 2009 1:20:38 AM com.sun.jersey.api.core.PackagesResourceConfig init
      INFO: Scanning for root resource and provider classes in the packages:
        restHello
      Dec 8, 2009 1:20:38 AM com.sun.jersey.api.core.PackagesResourceConfig init
      INFO: Root resource classes found:
        class restHello.MyResource
      Dec 8, 2009 1:20:38 AM com.sun.jersey.api.core.PackagesResourceConfig init
      INFO: Provider classes found:
      Dec 8, 2009 1:20:38 AM com.sun.jersey.server.impl.application.
      			WebApplicationImpl initiate
      INFO: Initiating Jersey application, version 'Jersey: 1.1.4.1 11/24/2009 01:30 AM'
      Hit ENTER for redeploy

Example: Creating a Simple Hello World Application Using JAX-RS and Jersey

This section discusses the simple RESTful web service that is included with the tutorial examples in the directory jaxrs/JAXRSHelloWorld. This example was created by following the steps similar to those described in Creating a RESTful Web Service Using NetBeans IDE.

JAXRSHelloWorld Example: Discussion

With this simple application, a simple root resource for a RESTful web service was selected. This generates a RESTful root resource class with GET and PUT methods. This design is useful for creating examples such as this simple Hello World service.

In this example, the method getHtml() is annotated with @GET and the @Produces("text/html") annotation. This method will process HTTP GET requests and produce content in HTML. To finish this example, you simply need to replace the current contents of this example with a statement that returns Hello World. This example has also replaced the name of the method with the name sayHello. Here is the code for the completed sayHello() method:

@GET
    @Produces("text/html")
    public String sayHello() {
        return "Hello World";
    }

ProcedureTesting the JAXRSHelloWorld Example

  1. Open the project javaeetutorial/jaxrs/JAXRSHelloWorld in NetBeans IDE.

  2. Right-click the project node, JAXRSHelloWorld, and select Test RESTful Web Services.

  3. Click the helloWorld service in the left pane.

  4. The Get(text/html) method is selected by default. Click Test.

  5. The response Hello World, displays in the lower pane, as shown in the following figure.

    Figure 13–1 Testing JAXRSHelloWorld Web Service

    Browser displaying the result of testing the helloWorld
method, which is the words Hello World in a section of the window titled Response.

ProcedureDeploying and Running the JAXRSHelloWorld Example

Before You Begin

The application's Run properties must be set to run the RESTful web service. For the provided application, this task has been completed. For future reference, right-click the project node, select Properties, then select Run, and enter the Relative URL. For this example, you would enter /resources/helloWorld.

  1. Right-click the project node, JAXRSHelloWorld, and select Deploy.

  2. Right-click the project node, JAXRSHelloWorld, and select Run.

  3. A browser opens and displays Hello World at the URL http://localhost:8080/HelloWorld/resources/helloWorld.

    The browser displays the text “Hello World”.

Example: Adding on to the Simple Hello World RESTful Web Service

This section discusses the simple RESTful web service that is included with the tutorial examples in the directory jaxrs/HelloWorld3. This example was created by following the steps similar to those described in Creating a RESTful Web Service Using NetBeans IDE.

HelloWorld3 Example: Discussion

This example takes the simple Hello World application discussed in the previous section and adds to it. In this example, there are methods for getting a user's name, and then the name is appended to the Hello World greeting. An annotation that wasn't used in the previous example, @QueryParam, is used in this example.

In this example, there is a simple RESTful web service that returns HTML messages. To accomplish this task, you would first create a class that uses Java Architecture for XML Binding (JAXB). This class represents the HTML message in Java (RESTGreeting.java), then creates a RESTful web service that returns an HTML message (HelloGreetingService.java.)

The JAXB class that represents the HTML message gets the message and the name. This file, RESTGreeting.java, is basic Java code that creates a new instance of RESTGreeting and the getter and setter methods for its parameters.

The RESTful web service that returns an HTML message is in the file HelloGreetingService.java. You may notice that method that is annotated with JAX-RS annotations is similar to the one described in the previous example, however, this example adds an @QueryParam annotation to extract query parameters from the Query component of the request URL. The following code example shows the JAX-RS-annotated method:

@GET
    @Produces("text/html")
    public RESTGreeting getHtml(@QueryParam("name")String name) {
        return new RESTGreeting(getGreeting(), name);
    }     
    private String getGreeting(){
        return "Hello ";
    }

ProcedureTesting the HelloWorld3 Example

  1. Open the project javaeetutorial/jaxrs/HelloWorld3 in NetBeans IDE.

  2. Right-click the project node, HelloWorld3, and select Test RESTful Web Services.

  3. Click the helloGreeting service in the left pane.

  4. Enter a name in the name text field.

  5. The Get(text/html) method is selected by default. Click Test.

  6. The response Hello name, displays in the Response pane, under the Raw View tab.

ProcedureDeploying and Running the HelloWorld3 Example

Before You Begin

The application's Run properties must be set to run the RESTful web service. For the provided application, this task has been completed. For future reference, right-click the project node, select Properties, then select Run, and enter the Relative URL. For this example, you would enter /helloGreeting.

  1. Right-click the project node, HelloWorld3, and select Deploy.

  2. Right-click the project node, HelloWorld3, and select Run.

    The Run property does not specify a particular name, so none is shown in the browser window when it displays. The browser window simply shows the message Hello.

  3. Append a name to the URL in the web browser, so that the URL looks like this: http://localhost:8080/HelloWorld3/helloGreeting?name=your_name.

  4. The message Hello and the name your_name display in the browser.

JAX-RS in the First Cup Example

JAX-RS is used in the Your First Cup of Java example, which you will find at Your First Cup: An Introduction to the Java EE Platform

Real World Examples

A few real-world web applications that use RESTful web services include most blog sites. These are considered RESTful in that most blog sites involve downloading XML files in RSS or Atom format which contain lists of links to other resources. Other web sites and web applications that use REST-like developer interfaces to data include Twitter and Amazon S3 (Simple Storage Service). With Amazon S3, buckets and objects can be created, listed, and retrieved using either a REST-style HTTP interface or a SOAP interface. The examples that ship with Jersey include a storage service example with a RESTful interface. The tutorial at http://netbeans.org/kb/docs/websvc/twitter-swing.html uses the NetBeans IDE to create a simple, graphical, REST-based client that displays Twitter public time line messages and lets you view and update your Twitter status.

Further Information

The information in this tutorial focuses on learning about JAX-RS and Jersey. If you are interested in learning more about RESTful Web Services in general, here are a few links to get you started.

Some of the Jersey team members discuss topics out of the scope of this tutorial on their blogs. A few are listed below:

You can always get the latest technology and information by visiting the Java Developer's Network. The links are listed below: