1.Before you continue to Learn Web Services, you should have a basic understanding of the following:
- HTML
- XML
3.Web services are open standard ( XML, SOAP, HTTP etc.) based Web applications that interact with other web applications for the purpose of exchanging data
4.Web Services can convert your existing applications into Web-applications
5.A web service is any piece of software that makes itself available over the internet and uses a standardized XML messaging system. XML is used to encode all communications to a web service. For example, a client invokes a web service by sending an XML message, then waits for a corresponding XML response. Because all communication is in XML, web services are not tied to any one operating system or programming language--Java can talk with Perl; Windows applications can talk with Unix applications.
6.Web Services are self-contained, modular, distributed, dynamic applications that can be described, published, located, or invoked over the network to create products, processes, and supply chains. These applications can be local, distributed, or Web-based. Web services are built on top of open standards such as TCP/IP, HTTP, Java, HTML, and XML.
7.Web services are XML-based information exchange systems that use the Internet for direct application-to-application interaction. These systems can include programs, objects, messages, or documents
8.A web service is a collection of open protocols and standards used for exchanging data between applications or systems. Software applications written in various programming languages and running on various platforms can use web services to exchange data over computer networks like the Internet in a manner similar to inter-process communication on a single computer. This interoperability (e.g., between Java and Python, or Windows and Linux applications) is due to the use of open standards
Types of Web Services?
There are basic two types of Web Services given bellow
1.Big webservices 2.RESTful webservices 1.Big Webservices: Big web services use XML messages that follow the Simple Object Access Protocol (SOAP) standard, an XML language defining a message architecture and message formats. Such systems often contain a machine-readable description of the operations offered by the service, written in the Web Services Description Language (WSDL), an XML language for defining interfaces syntactically The SOAP message format and the WSDL interface definition language have gained widespread adoption. Many development tools, such as NetBeans IDE, can reduce the complexity of developing web service applications
A SOAP-based design must include the following elements.
Building Web Services with JAX-WS
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 Remote Procedure Call-oriented (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 W3C: HTTP, SOAP, and WSDL. WSDL specifies an XML format for describing a service as a set of endpoints operating on messages.
Web services platform elements:
CWeb service is a system that enables applications to communicate with an API. Web service helps to expose business logic through an API interface where different systems communicate over network. At higher level there are two parties involved, party providing the service is web service provider and the one utilizing it is web service consumer. In a previous hello world tutorial for web service we discussed about creating a service based on soap using Netbeans. This micro tutorial will help understand some important jargon related to web services. In near future we will see tutorials based on Eclipse to create web services.![]() Generally,
Components of a Web ServiceThis is to highlight some of the important jargons related to web services.wsdlWeb Services Description Language (WSDL) is used to describe a web service in an XML file. It covers all the aspects of a web service like what is the message format, communication protocol, endpoint, security etc. This is a standard provided by W3C consortium and widely accepted for web services description.A wsdl xml file for a web service is generally expected to be published publicly so that parties seeking to utilize its services can understand the nature of service and consume it accordingly. TypesTypes is an important element in WSDL. It is used to describe the message attributes and respective types. XSD is the preferred format to describe the types. Type definition can be given in a separate XSD file and imported in WSDL.
UDDIUniversal Description, Discovery and Integration (UDDI) is a directory service. Web services can register with a UDDI and make themselves available through it for discovery. It is like a marriage broker :-) People ready to get married will describe themselves in a standard format (WSDL) and register with this directory. People seeking pair will approach this directory and discover based on the information provided and approach.Stub and SkeletonStub and skeleton are counterparts in a web service setup. Skeleton belongs to service provider side and stub belongs to receiver side. At lower level stub and skeleton communicate with each other. From client side the business objects communicates with stub objects and stub takes the responsibility form the message and invoke the web service. Once the invoking is done, at service provider side, skeleton is the parallel object for stub and it receives the request message and understands it and passes on the information to service side business objects.EndpointAn endpoint is a particular network location with associated protocol which includes message format mapping using which we can access that instance of web service. This is described in WSDL file. Consider this as a handle using which we will access the web service.BindingAssociating an interface with a protocol and message format is binding. It is used in endpoint definition. Binding is described in WSDL.OperationA single logical grouping of a meaningful action which comprises a request and response is an operation. Group of operations forms a web service.SOAPSimple Object Access Protocol is a XML based specification for web services message format and communication over network. That is it helps to describe the transport method and message format in a web service.MessageData that is used to communicate to and fro with a web service is a message. It is a standalone entity which comprises of complete information for a request or a response.Web Service DesignAs given in diagram a web service has logic and an interface. Logic is the actual service provided and interface is used to communicate with the web service. Interface definition is given in WSDL. There are two approaches in implementing a web service and they are bottom-up and top-down.Bottom Up ApproachBottom up approach is where we first define the logic of a web service and then using that we will build the interface. Service code is written first and then the WSDL is created using the service code. There are tools available to generate the wsdl file automatically based on it.Top Down ApproachTop down is the reverse of bottom up approach. First the service definition is written up. WSDL is created first. The complete service definition, message format, transport protocol, security and everything is described in WSDL. Then service is written after the WSDL. Using that wsdl the skeleton code is generated automatically and after that the service code is filled up.
|
Web Services Interoperability and JAX-WS
JAX-WS 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 the Dynamic Invocation Interface (DII).
What Are RESTful Web Services?
RESTful web services 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 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 by using a standardized interface and protocol.The following principles encourage RESTful applications to be simple, lightweight, and fast:
- Resource identification through URI: A RESTful web service exposes a set of resources that identify the targets of the interaction with its clients. Resources are identified by URIs, which provide a global addressing space for resource and service discovery. See The @Path Annotation and URI Path Templates for more information.
- Uniform interface: Resources are manipulated using a fixed set of four create, read, update, delete operations: PUT, GET, POST, and DELETE. PUT creates a new resource, which can be then deleted by using DELETE. GET retrieves the current state of a resource in some representation. POST transfers a new state onto a resource. See Responding to HTTP Methods and Requests for more information.
- Self-descriptive messages: Resources are decoupled from their representation so that their content can be accessed in a variety of formats, such as HTML, XML, plain text, PDF, JPEG, JSON, and others. Metadata about the resource is available and used, for example, to control caching, detect transmission errors, negotiate the appropriate representation format, and perform authentication or access control. See Responding to HTTP Methods and Requests and Using Entity Providers to Map HTTP Response and Request Entity Bodies for more information.
- Stateful interactions through hyperlinks: Every interaction with a resource is stateless; that is, request messages are self-contained. Stateful interactions are based on the concept of explicit state transfer. Several techniques exist to exchange state, such as URI rewriting, cookies, and hidden form fields. State can be embedded in response messages to point to valid future states of the interaction. See Using Entity Providers to Map HTTP Response and Request Entity Bodies and “Building URIs” in the JAX-RS Overview document for more information.
Creating a RESTful Root Resource Class
Root resource classes are POJOs 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 explains how to use JAX-RS to annotate Java classes to create RESTful web services.
Developing RESTful Web Services with JAX-RS
JAX-RS 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 JAX-RS annotations to define resources and the actions that can be performed on those resources. JAX-RS annotations are runtime annotations; therefore, runtime reflection will generate the helper classes and artifacts for the resource. A Java EE application archive containing JAX-RS resource classes will have the resources configured, the helper classes and artifacts generated, and the resource exposed to clients by deploying the archive to a Java EE server.
Table 20-1 lists 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 APIs can be viewed at http://docs.oracle.com/javaee/6/api/.
Table 20-1 Summary of JAX-RS AnnotationsAnnotationDescriptionThe @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: /helloworld/{username}.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.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.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.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.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.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.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.The @Consumes annotation is used to specify the MIME media types of representations a resource can consume that were sent by the client.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".The @Provider annotation is used for anything that is of interest to the JAX-RS runtime, such as MessageBodyReader andMessageBodyWriter. 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 by using a MessageBodyWriter. If the application needs to supply additional metadata, such as HTTP headers or a different status code, a method can return aResponse that wraps the entity and that can be built using Response.ResponseBuilder.Overview of a JAX-RS Application
The following code sample is a very simple example of a root resource class that uses JAX-RS annotations:
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’s value is a relative URI path. In the preceding example, the Java class will be hosted at the URI path /helloworld. This is an extremely simple use of the @Path annotation, with a static URI path. Variables can be embedded in the URIs. URI path templates are URIs with variables embedded within the URI syntax.
- The @GET annotation is a request method designator, along with @POST, @PUT, @DELETE, and @HEAD, defined by JAX-RS and corresponding to the similarly named HTTP methods. In the example, the annotated Java method will process HTTP GET requests. The behavior of a resource is determined by the HTTP method to which the resource is responding.
- The @Produces annotation is used to specify the MIME media types a resource can produce and send back to the client. In this example, the Java method will produce representations identified by the MIME media type "text/plain".
- The @Consumes annotation is used to specify the MIME media types a resource can consume that were sent by the client. The example could be modified to set the message returned by the getClichedMessage method, as shown in this code example:
@POST @Consumes("text/plain") public void postClichedMessage(String message) { // Store the message }
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 or method level of a resource. The @Pathannotation’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 application, and the URL pattern to which the JAX-RS runtime 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 braces ({ and }). For example, look at the following @Path annotation:
@Path("/users/{username}")
In this kind of example, a user is prompted to type his or her name, and then a JAX-RS web service configured to respond to requests to this URI path template responds. For example, if the user types the user name “Galileo,” the web service responds to the following URL:
http://example.com/users/Galileo
To obtain the value of the user name, the @PathParam annotation 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) { ... } }
By default, the URI variable must match the regular expression "[^/]+?". This variable may be customized by specifying a different regular expression after the variable name. For example, if a user name must consist only of lowercase and uppercase alphanumeric characters, override the default regular expression in the variable definition:
@Path("users/{username: [a-zA-Z][a-zA-Z_0-9]*}")
In this example the username variable will match only user names that begin with one uppercase or lowercase letter and zero or more alphanumeric characters and the underscore character. If a user name does not match that template, a 404 (Not Found) response will be sent to the client.
A @Path value isn’t required to have leading or trailing slashes (/). The JAX-RS runtime parses URI path templates the same whether or not they have leading or trailing spaces.
A URI path template has one or more variables, with each variable name surrounded by braces: { to begin the variable name and } to end it. In the preceding example, username is the variable name. At runtime, a resource configured to respond to the preceding 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/resources/{name1}/{name2}/, you must deploy the application 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 JAX-RS helper servlet, specified in web.xml, is the default:
<servlet-mapping> <servlet-name>My JAX-RS Resource</servlet-name> <url-pattern>/resources/*</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.
When defining URI path templates, be careful that the resulting URI after substitution is valid.
Table 20-2 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:
- name1: james
- name2: gatz
- name3:
- location: Main%20Street
- question: why
Note - The value of the name3 variable is an empty string.
Table 20-2 Examples of URI Path TemplatesURI Path TemplateURI After Substitutionhttp://example.com/{name1}/{name2}/http://example.com/james/gatz/http://example.com/{question}/{question}/{question}/http://example.com/why/why/why/http://example.com/maps/{location}http://example.com/maps/Main%20Streethttp://example.com/{name3}/home/http://example.com//home/Responding to HTTP Methods and Requests
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
Request method designator annotations are runtime annotations, defined by JAX-RS, that correspond to the similarly named HTTP methods. Within a resource class file, HTTP methods are mapped to Java programming language methods by using the request method designator annotations. The behavior of a resource is determined by which HTTP method the resource is responding to. JAX-RS defines a set of request method designators for the common HTTP methods @GET,@POST, @PUT, @DELETE, and @HEAD; you can also create your own custom request method designators. Creating custom request method designators is outside the scope of this document.
The following example, an extract from the storage service sample, shows the use of the PUT method 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 supported by the resource. In addition, the JAX-RS runtime will return a Web Application Definition Language (WADL) document describing the resource; seehttp://www.w3.org/Submission/wadl/ for more information.
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 by 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 the Response class. The ResponseBuilder class provides a convenient way to create aResponse 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.
Both @PUT and @POST can be used to create or update a resource. POST can mean anything, so when using POST, it is up to the application to define the semantics.PUT has well-defined semantics. When using PUT for creation, the client declares the URI for the newly created resource.
PUT has very clear semantics for creating and updating a resource. The representation the client sends must be the same representation that is received using aGET, given the same media type. PUT does not allow a resource to be partially updated, a common mistake when attempting to use the PUT method. A common application pattern is to use POST to create a resource and return a 201 response with a location header whose value is the URI to the newly created resource. In this pattern, the web service declares the URI for the newly created resource.
Using Entity Providers to Map HTTP Response and Request Entity Bodies
Entity providers supply mapping services between representations and their associated Java types. The two types of entity providers are MessageBodyReaderand 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 by 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 that can be built by using Response.ResponseBuilder.
Table 20-3 shows the standard types that are supported automatically for HTTP request and response entity bodies. You need to write an entity provider only if you are not choosing one of these standard types.
Table 20-3 Types Supported for HTTP Request and Response Entity Bodies
The following example shows how to use MessageBodyReader with the @Consumes and @Provider annotations:Java TypeSupported Media Typesbyte[]All media types (*/*)java.lang.StringAll text media types (text/*)java.io.InputStreamAll media types (*/*)java.io.ReaderAll media types (*/*)java.io.FileAll media types (*/*)javax.activation.DataSourceAll media types (*/*)javax.xml.transform.SourceXML media types (text/xml, application/xml, and application/*+xml)javax.xml.bind.JAXBElement and application-supplied JAXB classesXML media types (text/xml, application/xml, and application/*+xml)MultivaluedMap<String, String>Form content (application/x-www-form-urlencoded)StreamingOutputAll media types (*/*), MessageBodyWriter only
@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 following annotations:- javax.ws.rs.Consumes
- javax.ws.rs.Produces
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 applied at the method level, the annotation 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 JAX-RS 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 @Producesannotation 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 than 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 declares 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, 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 is acceptable. If both are equally acceptable, the former will be chosen because it occurs first. The preceding examples 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 athttp://jsr311.java.net/nonav/releases/1.0/javax/ws/rs/core/MediaType.html.
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 applied at the method level, @Consumes overrides any @Consumesannotations applied at the class level.
If a resource is unable to consume the MIME type of a client request, the JAX-RS 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 @Consumesannotation to specify that it can accept URL-encoded form data.
If no resource methods can respond to the requested MIME type, an HTTP 415 (“Unsupported Media Type”) error is returned to the client.
The HelloWorld example discussed previously in this section can be modified to set the message by 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. Note that the resource method returns void. This means that no representation is returned and that a 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.
You can extract the following types of parameters for use in your resource class:
- Query
- URI path
- Form
- Cookie
- Header
- Matrix
@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 the query parameter step exists in the query component of the request URI, the value of step will be extracted and parsed as a 32-bit signed integer and assigned to the step method parameter. If step does not exist, a default value of 2, as declared in the @DefaultValue annotation, will be assigned to the stepmethod parameter. If the step value cannot be parsed as a 32-bit signed integer, an HTTP 400 (“Client Error”) response is returned.
User-defined Java programming language types may be used as query parameters. The following code example shows the ColorParam class used in the preceding query parameter example:
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); } } } }
The constructor for ColorParam takes a single String parameter.
Both @QueryParam and @PathParam can be used only on the following Java types:
- All primitive types except char
- All wrapper classes of primitive types except Character
- Any class with a constructor that accepts a single String argument
- Any class with the static method named valueOf(String) that accepts a single String argument
- List<T>, Set<T>, or SortedSet<T>, where T matches the already listed criteria. Sometimes, parameters may contain more than one value for the same name. If this is the case, these types may be used to obtain all values
URI path parameters are extracted from the request URI, and the parameter names correspond to the URI path template variable names specified in the @Pathclass-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 preceding 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 JAX-RS runtime returns an HTTP 400 (“Bad Request”) error to the client. If the @PathParamannotation cannot be cast to the specified type, the JAX-RS 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, extract information from the HTTP headers. Matrix parameters, indicated by decorating the parameter with javax.ws.rs.MatrixParam, extract information from URL path segments.
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 inhttp://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1. This parameter is very useful for extracting information sent by POST in HTML forms.
The following example extracts the name form parameter from the POST form data:
@POST @Consumes("application/x-www-form-urlencoded") public void post(@FormParam("name") String name) { // Store the message }
To obtain a general map of parameter names and values for query and path parameters, use the following code:
@GET public String get(@Context UriInfo ui) { MultivaluedMap<String, String> queryParams = ui.getQueryParameters(); MultivaluedMap<String, String> pathParams = ui.getPathParameters(); }
The following method extracts header and cookie parameter names and values into a map:
@GET public String get(@Context HttpHeaders hh) { MultivaluedMap<String, String> headerParams = hh.getRequestHeaders(); Map<String, Cookie> pathParams = hh.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 }
xample Applications for JAX-RS
This section provides an introduction to creating, deploying, and running your own JAX-RS applications. This section demonstrates the steps that are needed to create, build, deploy, and test a very simple web application that uses JAX-RS annotations.A RESTful Web Service
This section explains how to use NetBeans IDE to create a RESTful web service. NetBeans IDE generates a skeleton for the application, and you simply need to implement the appropriate methods. If you do not use an IDE, try using one of the example applications that ship with Jersey as a template to modify.You can find a version of this application at tut-install/examples/jaxrs/HelloWorldApplication/.To Create a RESTful Web Service Using NetBeans IDE
- In NetBeans IDE, create a simple web application. This example creates a very simple “Hello, World” web application.
- From the File menu, choose New Project.
- 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.
- Type a project name, HelloWorldApplication, and click Next.
- Make sure that the Server is GlassFish Server (or similar wording).
- Click Finish.
- Right-click the project and select New; then select RESTful Web Services from Patterns.
- Select Simple Root Resource and click Next.
- Type a Resource Package name, such as helloWorld.
- Type helloworld in the Path field. Type HelloWorld in the Class Name field. For MIME Type, select text/html.
- Click Finish.The REST Resources Configuration page appears.
- Click OK.A new resource, HelloWorld.java, is added to the project and appears in the Source pane. This file provides a template for creating a RESTful web service.
- 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 produced 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 lang=\"en\"><body><h1>Hello, World!!</body></h1></html>"; }
- Test the web service. To do this, right-click the project node and click Test RESTful Web Services.This step deploys the application and brings up a test client in the browser.
- When the test client appears, select the helloworld resource in the left pane, and click the Test button in the right pane.The words Hello, World!! appear in the Response window below.
- Set the Run Properties:
- Right-click the project node and select Properties.
- In the dialog, 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, the file index.jsp will appear by default 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.
- Right-click the project and select Deploy.
- Right-click the project and select Run.A browser window opens and displays the return value of Hello, World!!
See AlsoFor other sample applications that demonstrate deploying and running JAX-RS applications using NetBeans IDE, see The rsvp Example Application and Your First Cup: An Introduction to the Java EE Platform at http://docs.oracle.com/javaee/6/firstcup/doc/. You may also look at the tutorials on the NetBeans IDE tutorial site, such as the one titled “Getting Started with RESTful Web Services” at http://www.netbeans.org/kb/docs/websvc/rest.html. 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.The rsvp Example Application
The rsvp example application, located in the tut-install/examples/jaxrs/rsvp/ directory, allows invitees to an event to indicate whether they will attend. The events, people invited to the event, and the responses to the invite are stored in a Java DB database using the Java Persistence API. The JAX-RS resources in rsvpare exposed in a stateless session enterprise bean.Components of the rsvp Example Application
The three enterprise beans in the rsvp example application are rsvp.ejb.ConfigBean, rsvp.ejb.StatusBean, and rsvp.ejb.ResponseBean.ConfigBean is a singleton session bean that initializes the data in the database.StatusBean exposes a JAX-RS resource for displaying the current status of all invitees to an event. The URI path template is declared as follows:@Path("/status/{eventId}/")
The URI path variable eventId is a @PathParam variable in the getResponse method, which responds to HTTP GET requests and has been annotated with @GET. The eventId variable is used to look up all the current responses in the database for that particular event.ResponseBean exposes a JAX-RS resource for setting an invitee’s response to a particular event. The URI path template for ResponseBean is declared as follows:@Path("/{eventId}/{inviteId}")
Two URI path variables are declared in the path template: eventId and inviteId. As in StatusBean, eventId is the unique ID for a particular event. Each invitee to that event has a unique ID for the invitation, and that is the inviteId. Both of these path variables are used in two JAX-RS methods in ResponseBean:getResponse and putResponse. The getResponse method responds to HTTP GET requests and displays the invitee’s current response and a form to change the response.An invitee who wants to change his or her response selects the new response and submits the form data, which is processed as an HTTP PUT request by theputResponse method. One of the parameters to the putResponse method, the userResponse string, is annotated with @FormParam("attendeeResponse"). The HTML form created by getResponse stores the changed response in the select list with an ID of attendeeResponse. The annotation@FormParam("attendeeResponse") indicates that the value of the select response is extracted from the HTTP PUT request and stored as the userResponsestring. The putResponse method uses userResponse, eventId, and inviteId to update the invitee’s response in the database.The events, people, and responses in rsvp are encapsulated in Java Persistence API entities. The rsvp.entity.Event, rsvp.entity.Person, andrsvp.entity.Response entities respectively represent events, invitees, and responses to an event.The rsvp.util.ResponseEnum class declares an enumerated type that represents all the possible response statuses an invitee may have.Running the rsvp Example Application
Both NetBeans IDE and Ant can be used to deploy and run the rsvp example application.To Run the rsvp Example Application in NetBeans IDE
- From the File menu, choose Open Project.
- In the Open Project dialog, navigate to:
tut-install/examples/jaxrs/
- Select the rsvp folder.
- Select the Open as Main Project check box.
- Click Open Project.
- Right-click the rsvp project in the left pane and select Run.The project will be compiled, assembled, and deployed to GlassFish Server. A web browser window will open to http://localhost:8080/rsvp.
- In the web browser window, click the Event Status link for the Duke’s Birthday event.You’ll see the current invitees and their responses.
- Click on the name of one of the invitees, select a response, and click Submit response; then click Back to event page.The invitee’s new status should now be displayed in the table of invitees and their response statuses.
To Run the rsvp Example Application Using Ant
Before You BeginYou must have started the Java DB database before running rsvp.- In a terminal window, go to:
tut-install/examples/jaxrs/rsvp/
- Type the following command:
ant all
This command builds, assembles, and deploys rsvp to GlassFish Server. - Open a web browser window to http://localhost:8080/rsvp.
- In the web browser window, click the Event Status link for the Duke’s Birthday event.You’ll see the current invitees and their responses.
- Click on the name of one of the invitees, select a response, and click Submit response, then click Back to event page.The invitee’s new status should now be displayed in the table of invitees and their response statuses.
Real-World Examples
Most blog sites use RESTful web services. These sites involve downloading XML files, in RSS or Atom format, that 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 NetBeans IDE to create a simple, graphical, REST-based client that displays Twitter public timeline messages and lets you view and update your Twitter status.Annotations for Field and Bean Properties of Resource Classes
JAX-RS annotations for resource classes let you extract specific parts or values from a Uniform Resource Identifier (URI) or request header. JAX-RS provides the annotations listed in Table 21-1.Table 21-1 Advanced JAX-RS AnnotationsAnnotationDescription@ContextInjects information into a class field, bean property, or method parameter@CookieParamExtracts information from cookies declared in the cookie request header@FormParamExtracts information from a request representation whose content type is application/x-www-form-urlencoded@HeaderParamExtracts the value of a header@MatrixParamExtracts the value of a URI matrix parameter@PathParamExtracts the value of a URI template parameter@QueryParamExtracts the value of a URI query parameterExtracting Path Parameters
URI path templates are URIs with variables embedded within the URI syntax. The @PathParam annotation lets you use variable URI path fragments when you call a method. The following code snippet shows how to extract the last name of an employee when the employee’s email address is provided:@Path(/employees/"{firstname}.{lastname}@{domain}.com") public class EmpResource { @GET @Produces("text/xml") public String getEmployeelastname(@PathParam("lastname") String lastName) { ... } }
In this example, the @Path annotation defines the URI variables (or path parameters) {firstname} , {lastname}, and {domain}. The @PathParam in the method parameter of the request method extracts the last name from the email address. If your HTTP request is GET /employees/john.doe@example.com, the value “doe” is injected into {lastname}. You can specify several path parameters in one URI. You can declare a regular expression with a URI variable. For example, if it is required that the last name must consist only of lower and upper case characters, you can declare the following regular expression:@Path(/employees/{"firstname}.{lastname[a-zA-Z]*}@{domain}.com")
If the last name does not match the regular expression, a 404 response is returned.Extracting Query Parameters
Use the @QueryParam annotation to extract query parameters from the query component of the request URI. For instance, to query all employees who have joined within a specific range of years, use a method signature like the following:@Path(/employees/") @GET public Response getEmployees( @DefaultValue("2002") @QueryParam("minyear") int minyear, @DefaultValue("2010") @QueryParam("maxyear") int maxyear) {...}
This code snippet defines two query parameters, minyear and maxyear. The following HTTP request would query for all employees who have joined between 1999 and 2009:GET /employees?maxyear=2009&minyear=1999
The @DefaultValue annotation defines a default value, which is to be used if no values are provided for the query parameters. By default, JAX-RS assigns a null value for Object values and zero for primitive data types. You can use the @DefaultValue annotation to eliminate null or zero values and define your own default values for a parameter.Extracting Form Data
Use the @FormParam annotation to extract form parameters from HTML forms. For example, the following form accepts the name, address, and manager’s name of an employee:<FORM action="http://example.com/employees/" method="post"> <p> <fieldset> Employee name: <INPUT type="text" name="empname" tabindex="1"> Employee address: <INPUT type="text" name="empaddress" tabindex="2"> Manager name: <INPUT type="text" name="managername" tabindex="3"> </fieldset> </p> </FORM>
Use the following code snippet to extract the manager name from this HTML form:@POST @Consumes("application/x-www-form-urlencoded") public void post(@FormParam("managername") String managername) { // Store the value ... }
To obtain a map of form parameter names to values, use a code snippet like the following:@POST @Consumes("application/x-www-form-urlencoded") public void post(MultivaluedMap<String. String> formParams) { // Store the message }
Extracting the Java Type of a Request or Response
The javax.ws.rs.core.Context annotation retrieves the Java types related to a request or response. The javax.ws.rs.core.UriInfo interface provides information about the components of a request URI. The following code snippet shows how to obtain a map of query and path parameter names to values:@GET public String getParams(@Context UriInfo ui) { MultivaluedMap<String, String> queryParams = ui.getQueryParameters(); MultivaluedMap<String, String> pathParams = ui.getPathParameters(); }
The javax.ws.rs.core.HttpHeaders interface provides information about request headers and cookies. The following code snippet shows how to obtain a map of header and cookie parameter names to values:@GET public String getHeaders(@Context HttpHeaders hh) { MultivaluedMap<String, String> headerParams = hh.getRequestHeaders(); MultivaluedMap<String, Cookie> pathParams = hh.getCookies(); }
Subresources and Runtime Resource Resolution
You can use a resource class to process only a part of the URI request. A root resource can then implement subresources that can process the remainder of the URI path.A resource class method that is annotated with @Path is either a subresource method or a subresource locator:- A subresource method is used to handle requests on a subresource of the corresponding resource.
- A subresource locator is used to locate subresources of the corresponding resource.
Subresource Methods
A subresource method handles an HTTP request directly. The method must be annotated with a request method designator such as @GET or @POST, in addition to@Path. The method is invoked for request URIs that match a URI template created by concatenating the URI template of the resource class with the URI template of the method.The following code snippet shows how a subresource method can be used to extract the last name of an employee when the employee’s email address is provided:@Path("/employeeinfo") Public class EmployeeInfo { public employeeinfo() {} @GET @Path("/employees/{firstname}.{lastname}@{domain}.com") @Produces("text/xml") public String getEmployeeLastName(@PathParam("lastname") String lastName) { ... } }
The getEmployeeLastName method returns doe for the following GET request:GET /employeeinfo/employees/john.doe@example.com
Subresource Locators
A subresource locator returns an object that will handle an HTTP request. The method must not be annotated with a request method designator. You must declare a subresource locator within a subresource class, and only subresource locators are used for runtime resource resolution.The following code snippet shows a subresource locator:// Root resource class @Path("/employeeinfo") public class EmployeeInfo { // Subresource locator: obtains the subresource Employee // from the path /employeeinfo/employees/{empid} @Path("/employees/{empid}") public Employee getEmployee(@PathParam("empid") String id) { // Find the Employee based on the id path parameter Employee emp = ...; ... return emp; } } // Subresource class public class Employee { // Subresource method: returns the employee's last name @GET @Path("/lastname") public String getEmployeeLastName() { ... return lastName } }
Using JAX-RS With JAXB
Java Architecture for XML Binding (JAXB) is an XML-to-Java binding technology that simplifies the development of web services by enabling transformations between schema and Java objects and between XML instance documents and Java object instances. An XML schema defines the data elements and structure of an XML document. You can use JAXB APIs and tools to establish mappings between Java classes and XML schema. JAXB technology provides the tools that enable you to convert your XML documents to and from Java objects.By using JAXB, you can manipulate data objects in the following ways:- You can start with an XML schema definition (XSD) and use xjc, the JAXB schema compiler tool, to create a set of JAXB-annotated Java classes that map to the elements and types defined in the XSD schema.
- You can start with a set of Java classes and use schemagen, the JAXB schema generator tool, to generate an XML schema.
- Once a mapping between the XML schema and the Java classes exists, you can use the JAXB binding runtime to marshal and unmarshal your XML documents to and from Java objects and use the resulting Java classes to assemble a web services application.
XML is a common media format that RESTful services consume and produce. To deserialize and serialize XML, you can represent requests and responses by JAXB annotated objects. Your JAX-RS application can use the JAXB objects to manipulate XML data. JAXB objects can be used as request entity parameters and response entities. The JAX-RS runtime environment includes standard MessageBodyReader and MessageBodyWriter provider interfaces for reading and writing JAXB objects as entities.With JAX-RS, you enable access to your services by publishing resources. Resources are just simple Java classes with some additional JAX-RS annotations. These annotations express the following:- The path of the resource (the URL you use to access it)
- The HTTP method you use to call a certain method (for example, the GET or POST method)
- The MIME type with which a method accepts or responds
As you define the resources for your application, consider the type of data you want to expose. You may already have a relational database that contains information you want to expose to users, or you may have static content that does not reside in a database but does need to be distributed as resources. Using JAX-RS, you can distribute content from multiple sources. RESTful web services can use various types of input/output formats for request and response. The customerexample, described in The customer Example Application, uses XML.Resources have representations. A resource representation is the content in the HTTP message that is sent to, or returned from, the resource using the URI. Each representation a resource supports has a corresponding media type. For example, if a resource is going to return content formatted as XML, you can useapplication/xml as the associated media type in the HTTP message. Depending on the requirements of your application, resources can return representations in a preferred single format or in multiple formats. JAX-RS provides @Consumes and @Produces annotations to declare the media types that are acceptable for a resource method to read and write.JAX-RS also maps Java types to and from resource representations using entity providers. A MessageBodyReader entity provider reads a request entity and deserializes the request entity into a Java type. A MessageBodyWriter entity provider serializes from a Java type into a response entity. For example, if a Stringvalue is used as the request entity parameter, the MessageBodyReader entity provider deserializes the request body into a new String. If a JAXB type is used as the return type on a resource method, the MessageBodyWriter serializes the JAXB object into a response body.By default, the JAX-RS runtime environment attempts to create and use a default JAXBContext class for JAXB classes. However, if the default JAXBContext class is not suitable, then you can supply a JAXBContext class for the application using a JAX-RS ContextResolver provider interface.The following sections explain how to use JAXB with JAX-RS resource methods.Using Java Objects to Model Your Data
If you do not have an XML schema definition for the data you want to expose, you can model your data as Java classes, add JAXB annotations to these classes, and use JAXB to generate an XML schema for your data. For example, if the data you want to expose is a collection of products and each product has an ID, a name, a description, and a price, you can model it as a Java class as follows:@XmlRootElement(name="product") @XmlAccessorType(XmlAccessType.FIELD) public class Product { @XmlElement(required=true) protected int id; @XmlElement(required=true) protected String name; @XmlElement(required=true) protected String description; @XmlElement(required=true) protected int price; public Product() {} // Getter and setter methods // ... }
Run the JAXB schema generator on the command line to generate the corresponding XML schema definition:schemagen Product.java
This command produces the XML schema as an .xsd file:<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="product" type="product"/> <xs:complexType name="product"> <xs:sequence> <xs:element name="id" type="xs:int"/> <xs:element name="name" type="xs:string"/> <xs:element name="description" type="xs:string"/> <xs:element name="price" type="xs:int"/> </xs:sequence> <xs:complexType> </xs:schema>
Once you have this mapping, you can create Product objects in your application, return them, and use them as parameters in JAX-RS resource methods. The JAX-RS runtime uses JAXB to convert the XML data from the request into a Product object and to convert a Product object into XML data for the response. The following resource class provides a simple example:@Path("/product") public class ProductService { @GET @Path("/get") @Produces("application/xml") public Product getProduct() { Product prod = new Product(); prod.setId(1); prod.setName("Mattress"); prod.setDescription("Queen size mattress"); prod.setPrice(500); return prod; } @POST @Path("/create") @Consumes("application/xml") public Response createProduct(Product prod) { // Process or store the product and return a response // ... } }
Some IDEs, such as NetBeans IDE, will run the schema generator tool automatically during the build process if you add Java classes that have JAXB annotations to your project. For a detailed example, see The customer Example Application. The customer example contains a more complex relationship between the Java classes that model the data, which results in a more hierarchical XML representation.Starting from an Existing XML Schema Definition
If you already have an XML schema definition in an .xsd file for the data you want to expose, use the JAXB schema compiler tool. Consider this simple example of an .xsd file:<?xml version="1.0"?> <xs:schema targetNamespace="http://xml.product" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns:myco="http://xml.product"> <xs:element name="product" type="myco:Product"/> <xs:complexType name="Product"> <xs:sequence> <xs:element name="id" type="xs:int"/> <xs:element name="name" type="xs:string"/> <xs:element name="description" type="xs:string"/> <xs:element name="price" type="xs:int"/> </xs:sequence> </xs:complexType> </xs:schema>
Run the schema compiler tool on the command line as follows:xjc Product.xsd
This command generates the source code for Java classes that correspond to the types defined in the .xsd file. The schema compiler tool generates a Java class for each complexType defined in the .xsd file. The fields of each generated Java class are the same as the elements inside the corresponding complexType, and the class contains getter and setter methods for these fields.In this case the schema compiler tool generates the classes product.xml.Product and product.xml.ObjectFactory. The Product class contains JAXB annotations, and its fields correspond to those in the .xsd definition:@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "Product", propOrder = { "id", "name", "description", "price" }) public class Product { protected int id; @XmlElement(required = true) protected String name; @XmlElement(required = true) protected String description; protected int price; // Setter and getter methods // ... }
You can create instances of the Product class from your application (for example, from a database). The generated class product.xml.ObjectFactorycontains a method that allows you to convert these objects to JAXB elements that can be returned as XML inside JAX-RS resource methods:@XmlElementDecl(namespace = "http://xml.product", name = "product") public JAXBElement<Product> createProduct(Product value) { return new JAXBElement<Product>(_Product_QNAME, Product.class, null, value); }
The following code shows how to use the generated classes to return a JAXB element as XML in a JAX-RS resource method:@Path("/product") public class ProductService { @GET @Path("/get") @Produces("application/xml") public JAXBElement<Product> getProduct() { Product prod = new Product(); prod.setId(1); prod.setName("Mattress"); prod.setDescription("Queen size mattress"); prod.setPrice(500); return new ObjectFactory().createProduct(prod); } }
For @POST and @PUT resource methods, you can use a Product object directly as a parameter. JAX-RS maps the XML data from the request into a Product object.@Path("/product") public class ProductService { @GET // ... @POST @Path("/create") @Consumes("application/xml") public Response createProduct(Product prod) { // Process or store the product and return a response // ... } }
Some IDEs, such as NetBeans IDE, will run the schema compiler tool automatically during the build process if you add an .xsd file to your project sources. For a detailed example, see Modifying the Example to Generate Entity Classes from an Existing Schema. The modified customer example contains a more hierarchical XML schema definition, which results in a more complex relationship between the Java classes that model the data.Using JSON with JAX-RS and JAXB
JAX-RS can automatically read and write XML using JAXB, but it can also work with JSON data. JSON is a simple text-based format for data exchange derived from JavaScript. For the examples above, the XML representation of a product is:<?xml version="1.0" encoding="UTF-8"?> <product> <id>1</id> <name>Mattress</name> <description>Queen size mattress</description> <price>500</price> </product>
The equivalent JSON representation is:{ "id":"1", "name":"Mattress", "description":"Queen size mattress", "price":500 }
You can add the format application/json to the @Produces annotation in resource methods to produce responses with JSON data:@GET @Path("/get") @Produces({"application/xml","application/json"}) public Product getProduct() { ... }
In this example the default response is XML, but the response is a JSON object if the client makes a GET request that includes this header:Accept: application/json
The resource methods can also accept JSON data for JAXB annotated classes:@POST @Path("/create") @Consumes({"application/xml","application/json"}) public Response createProduct(Product prod) { ... }
The client should include the following header when submitting JSON data with a POST request:Content-Type: application/json
No comments:
Post a Comment