📜 ⬆️ ⬇️

JAX-RS Basics

Introduction


This API has grown from JSR 311: JAX-RS: The Java API for RESTful Web Services and entered into Java EE 6 (it was planned in Java EE 5). As the name implies, it is intended to develop RESTful web services.

The main purpose of this article is to introduce the reader to the basics of the JAX-RS API. Initially, I planned to write about some of the problems of the forms when using the JAX-RS service. Not having found on Habré almost anything relating to this technology, I realized that the introduction to the article will not succeed.

The basics of the JAX-RS API, the implementation from JBoss will be presented and a small introduction to the client part of the Resteasy framework will be given.

')
It is represented by a set of classes in javax.ws.rs. * , In the case of modern AppServers, provided by the environment (you can use <scope>provided</scope> in maven . For applications in servlet containers, there are several implementations:


This technology allows the export of arbitrary bin methods using a special servlet provided by JAX-RS implementations. I will give an example. For use in the client part, select the interface:
 package com.example; import javax.ws.rs.*; @Path("/") public interface RestService { @GET @Path("echo") String echo(@QueryParam("q") String original); } 


And implementation:
 package com.example; import javax.enterprise.ApplicationScoped; import javax.ws.rs.*; @ApplicationScoped @Path("/") public class Rest implements RestService{ @GET @Path("echo") @Override public String echo(@QueryParam("q") String original) { return original; } } 


As to the bin itself, so annotations are added to its methods that describe its behavior: @Path , for example, indicates the relative or absolute path to this resource; annotation group @GET , @POST , @PUT , @DELETE is responsible for the type of HTTP request relevant to this method.

Serialization


Obviously, to transfer proivolnyh data, requires serialization - the transfer of data from the object representation in a set of bytes. Further story I will lead with an eye to Resteasy.
In this case, special providers are used for serialization / deserialization. The @Produces and @Consumes are used to indicate the MIME type of the content of the result / data. Accordingly, the data class must be annotated by JAXB . Standard providers in JBoss AS 7 are resteasy-jaxb-provider (xml-marshaller / anmarschaller) and resteasy-jettison-provider (json). These two providers allow you to integrate with a large number of external services, provide XML and JSON API to the outside.

Custom answers


What if we want to return a non-standard response or HTTP code? When Exception from an annotated JAX-RS method, the result is a 500 error. For customization, just return the type to specify javax.ws.rs.core.Response :
 @GET @Path("file/get/{name}") Response getFile(@PathParam("file") String fileName) { if(!Files.exists(Paths.get(fileName)) { return Response.status(422).entity("I'm a teapot"); } else { Response.Builder response = Response.ok(); response.header("X-Some-Server-Header", "value"); response.entity(new StreamingOutput() { @Override public void write(OutputStream outputStream) throws IOException, WebApplicationException { Files.copy(Paths.get(fileName), outputStream); } }); return response.build(); } } 


Client framework


The second pleasant moment of JBoss Resteasy is the presence of a convenient client framework. Working with it is possible at different levels of abstraction: starting from low-level ClientRequest , ClientResponse<T> and ending with the generation of proxy objects over an annotated JAX-RS interface. For example, using the RestService interface from the first example:
 RestService service = ProxyFactory.create(RestService.class, "http://localhost:8080/example"); log.info(service.echo("test message")); 


But sometimes this is not enough. For example, in this case, if an error occurs on the server side, the proxy generates an exception. For lower-level work, ClientRequest / ClientResponse<T> can be used, using apache httpcomponents (in Resteasy 2.3.x.GA) or apache-httpclient (in 2.2.x.GA). The usage example is as follows:
 ClientRequest request = new ClientRequest(url); request.header("X-Additional-Header", "header value"); //     : GET, POST, PUT, DELETE ClientResponse<String> response = request.get(String.class); if(response.getCode() == 200) { String result = response.getEntity(); log.info(result); } 


UPD: In case of using the client framework, it is necessary to initialize it once when starting the program as follows:
 RegisterBuiltin.register(ResteasyProviderFactory.getInstance()); 


This approach allows you to set arbitrary fields, arbitrarily the request body, etc.
One emerging problem in this case will be the next article.

UPD: Continued, see here .

Source: https://habr.com/ru/post/140181/


All Articles