Table des matières
Il faut commencer par créer un projet Web Dynamic avec le support de JAX-RS (REST Web Service).
Ensuite, il faut créer le serveur en créant une classe normale. Pour Jersey, il est indispensable que le serveur soit dans un package
non vide.
Dans l'exemple ci-dessous, il faut aussi pour Tomcat et le projet la librairie java-json.jar (à mettre dans le dossier WebContent/lib
) qui facilitera la réponse au client.
Attention, j'ai eu personnellement beaucoup de mal à faire fonctionner REST sur Eclipse. On pense que tout est bien configuré et ça ne marche pas pendant des heures. Puis d'un coup, on a l'impression que le projet tombe en marche miraculeusement… O_o
J'ai réussi plusieurs fois à faire fonctionner REST sans que JAX-RS
soit activé dans Project Facets
mais jamais avec. Donc prudence. Pareil, avec @Path
mais avec @ApplicationPath
ça ne marche pas (oui, j'ai bien fait hérité de la classe Application
).
- Serveur.java
package com.llgc; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; /* import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataParam; */ import org.json.JSONException; import org.json.JSONObject; @Path("/euro") public class Serveur { // Ici, le path est cumulatif avec le "/euro". // On fait donc bien référence au chemin "/euro/{f}" avec {f} : un nombre // flottant @Path("{f}") // Méthode GET @GET // Mime Type en sortie @Produces(MediaType.APPLICATION_XML) // Mime Type en entrée @Consumes(MediaType.APPLICATION_XML) // On dit que le f est extrait du path et que c'est un double. public String traitementXml(@PathParam("f") Double f) { return "<conversion><euros>" + f / 6.65 + "</euros><francs>" + f + "</francs></conversion>"; } @Path("{f}") @GET @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public String traitementJson(@PathParam("f") Double f) throws JSONException { JSONObject jsonObject = new JSONObject(); jsonObject.put("Francs", f); jsonObject.put("Euros", f / 6.65); return jsonObject.toString(); } @Path("{f}") @GET @Produces(MediaType.TEXT_HTML) @Consumes(MediaType.TEXT_HTML) public String traitementPlainHtml(@PathParam("f") Double f) throws JSONException { JSONObject jsonObject = new JSONObject(); jsonObject.put("FrancsHMTLHTMLHTML", f); jsonObject.put("Euris", f / 6.65); return jsonObject.toString(); } @GET @Path("/down") @Produces("image/png") // Le client veut télécharger public Response download() { File file = new File("image.png"); ResponseBuilder response = Response.ok((Object) file); response.header("Content-Disposition", "attachment; filename=test.png"); return response.build(); } @Path("/upload") @POST @Consumes(MediaType.MULTIPART_FORM_DATA) // Le client veut uploader public Response upload(@FormDataParam("file") InputStream uploadedInputStream, @FormDataParam("file") FormDataContentDisposition fileDetail) { String uploadedFileLocation = "./" + "Jersey_" + fileDetail.getFileName(); saveToFile(uploadedInputStream, uploadedFileLocation); String output = "File uploaded via Jersey based RESTFul Webservice to: " + uploadedFileLocation; return Response.status(200).entity(output).build(); } private void saveToFile(InputStream uploadedInputStream, String uploadedFileLocation) { try { OutputStream out = null; int read = 0; byte[] bytes = new byte[1024]; out = new FileOutputStream(new File(uploadedFileLocation)); while ((read = uploadedInputStream.read(bytes)) != -1) { out.write(bytes, 0, read); } out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); } } }
Utilisation d'un Bean pour architecturer ces données
public class MyBeanParam { @PathParam("p") private String pathParam; @MatrixParam("m") @Encoded @DefaultValue("default") private String matrixParam; @HeaderParam("header") private String headerParam; private String queryParam; public MyBeanParam(@QueryParam("q") String queryParam) { this.queryParam = queryParam; } public String getPathParam() { return pathParam; } } @POST public void post(@BeanParam MyBeanParam beanParam, String entity) { final String pathParam = beanParam.getPathParam(); // contains injected path parameter "p" ... }
JAX-RS Application, Resources and Sub-Resources Archive du 02/03/2020 le 27/04/2020
- web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>REST</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <description>JAX-RS Tools Generated - Do not modify</description> <servlet-name>JAX-RS Servlet</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>com.llgc</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>JAX-RS Servlet</servlet-name> <url-pattern>/convert/*</url-pattern> </servlet-mapping> </web-app>
Exemple de client
import java.net.URI; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; public class ClientJersey { public static void delete() { String url = "http://localhost:8080/client/del/0"; URI uri = URI.create(url); final Client client = ClientBuilder.newClient(); WebTarget webTarget = client.target(uri); Response response = webTarget.request().delete(); if (response.getStatus() != 200) { throw new RuntimeException("Failed : HTTP error code : " + response.getStatus()); } System.out.println("Output delete from Server .... \n" + response.getStatus()); } public static void main(String[] args) { try { delete(); String url = "http://localhost:8080/helloworld/xml"; URI uri = URI.create(url); final Client client = ClientBuilder.newClient(); WebTarget webTarget = client.target(uri); Response response = webTarget.request(MediaType.APPLICATION_XML).get(); if (response.getStatus() != 200) { throw new RuntimeException("Failed : HTTP error code : " + response.getStatus()); } String output = response.readEntity(String.class); System.out.println("Output XML from Server .... \n"); System.out.println(output); } catch (Exception e) { e.printStackTrace(); } } }
Erreurs
javax.servlet.ServletException: Aucune classe servlet n'a été spécifiée pour la servlet JAX-RS Servlet
Il faut spécifier dans web.xml
la classe Serveur :
<servlet> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>