DOC JERSEY

Intro

Jersey est un framework permettant de develloper des web service rest
Home du projet ici. Le user guide la. L 'api ici

Tous le code des exemples est dispos sur mon cvs source forge ici

Comme il s'agit d'un web service vous devait utiliser un serveur de servlette terme trés vague et générique pouvant deésigné pas mal de chose ...
J'en connais deux utilisé a mon taf TOMCAT et GRIZZLY
Grizzlly tous recement pour les test dit smok tests (test rapide) et tomcat pour la production

Hello

Si dessous vous trouverez les fichier du projet copier collez (pour le referencement) dispos sur mon sourceforge
Sa aide aussi pour avoir une vue d'ensemble utiliser control+f (firefox) pour chercher les partie interessante pour votre cas

Explication

Le web.xml fais la liaisons entre le framework et les url de type /WS/*
A noter que si vous faite un truc du style /* vous ne pourrez plus axceder a votre index.html et autre page web

Compil

Ce placer dans le repertoir et taper:
mvn war:exploded
On decompress le war pour pouvoir pointer le grissly et l'apache directement dessus
Pour eviter que le war prenne le nom du packahe rajouter name:Jersey1

test

Pour tester votre install lancer les class de test
Avec un navigateur lancer Jersey2.java (attention au port par default 8080)
Ensuite connecter vous à http://localhost:8080/
Vous devriez voir mon index.html + un commentaire devant qui vient de mon implem

Exemple d'organization

├── pom.xml ├── src │   ├── main │   │   ├── java │   │   │   └── com │   │   │      └── gadille │   │   │      ├── Form1.java │   │   │      ├── Form2.java │   │   │      ├── HelloWorldResource.java │   │   │      ├── LoadFile1.java │   │   │      ├── LoadFile2.java │   │   │      ├── LoadFile3.java │   │   │      └── LoadFile4.java │   │   └── webapp │   │   ├── index.html │   │   └── WEB-INF │   │   └── web.xml │   └── test │   ├── java │   │   └── com │   │      └── gadille │   │      ├── TestGrizHttpClient.java │   │      └── TestHello.java │   └── resources │   ├── ExtendedLeadsLog_20100802_1.gz │   ├── log4j.xml │   └── test.txt

Pom.xml

Il est assais volumineux car il contient plusieur morceaux et usages
Grizzly pour effectuer les tests mais il pourrais etre utlisé en temps que serveur de prode
Je n'est pas pousser dans les tests avec le client jersey car c'est contraire a la politique de ma boitte
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>gadille.free.fr</groupId> <artifactId>Jersey1</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>Jersey1</name> <dependencies> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-server</artifactId> <version>${jersey.version}</version> </dependency> <dependency> <groupId>com.sun.jersey.contribs</groupId> <artifactId>jersey-multipart</artifactId> <version>${jersey.version}</version> </dependency> <!-- for uploading file (apache jar) need by apache form --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.2.1</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>1.4</version> </dependency> </dependencies> <!-- for test --> <dependency> <groupId>com.sun.jersey.jersey-test-framework</groupId> <artifactId>jersey-test-framework-core</artifactId> <version>${jersey.version}</version> </dependency> <dependency> <groupId>com.sun.jersey.jersey-test-framework</groupId> <artifactId>jersey-test-framework-grizzly</artifactId> <version>${jersey.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>com.sun.grizzly</groupId> <artifactId>grizzly-servlet-webserver</artifactId> <version>1.9.19-SNAPSHOT</version> </dependency> <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> </dependency> <build> <finalName>Jersey1</finalName> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <inherited>true</inherited> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> <properties> <jersey.version>1.3</jersey.version> <mailinglist></mailinglist> <jdk.version>1.6</jdk.version> <product.name></product.name> <component.name></component.name> </properties> <repositories> <repository> <id>sun-repo-2</id> <url>http://download.java.net/maven/2/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>glassfish-repository</id> <name>Java.net Repository for Glassfish</name> <url>http://download.java.net/maven/glassfish</url> </repository> <repository> <id>maven2-repository.dev.java.net</id> <name>Java.net Repository for Maven</name> <url>http://download.java.net/maven/2/</url> <layout>default</layout> </repository> </repositories> </project>

web.xml

Il permet de faire la liaisons entre le code java et le serveur d'aplication (tomcat ou grizlly)
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <servlet-name>Jersey Web Application</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> <param-value>com.gadille</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Jersey Web Application</servlet-name> <url-pattern>/WS/*</url-pattern> </servlet-mapping> </web-app>

HelloWorldResource.java

package com.gadille; 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"; } }

Tomcat

Le propos et pas une formation tomcat reporter vous a ma page ici mais justes de vous aider a deployer votre hello world sur un tomcat
Il faut créer un context (tomcat arreté: /opt/tomcat-8080/bin/shutdown.sh)
cat /opt/tomcat-8080/conf/Catalina/localhost/Jersey1.xml


Puis fabriquer la webapp
cd /home/lio/workspace-perso/jersey1
mvn war:exploded
Cela va remplir le "target/Jersey1" (Jersey1 etant le parame name du pom.xml)
Demarrer votre tomcat
Et le resultat est visible sous http://localhost:8080/Jersey1

Grizzly Jersey

Voici un petit exemple de code pour lancer un serveur grizzly
String URL_PREFIX = "http://localhost:9998/Jersey1/WS/"; SelectorThread threadSelector; threadSelector = GrizzlyServerFactory.create(URL_PREFIX); System.out.println("Grizzly start on port 9998"); System.out.println("Attention grizzly ne sert pas du html mais que des servlette"); System.out.println("use url: http://localhost:8080/Jersey1/WS/helloworld to get hello"); System.out.println("hit enter to stop"); Scanner sc = new Scanner(System.in); sc.nextLine(); if (threadSelector != null)threadSelector.stopEndpoint(); System.out.println("Grizzly stop");
On utilise la class selector qui est de plus haut niveaux que GrizzlyWebServer
A noter que le serveur grizzly ne sert pas les pages html par default

Grizzly Jersey Http html static

Il vous faudra trouver une implementation ou en faire une
cf la mienne
ServletAdapter sa; GrizzlyWebServer ws = new GrizzlyWebServer(8080, contextPath); sa = new ServletAdapter(); sa.addInitParameter("com.sun.jersey.config.property.packages", "com.gadille.services"); sa.setContextPath("/jersey"); // obligatoir sinnon sert du 200 vide sa.setServletInstance(new ServletContainer()); ws.addGrizzlyAdapter(sa, new String[] { "/jersey" }); ws.addGrizzlyAdapter(new GrizzlyAdapter() { @SuppressWarnings("unchecked") @Override public void service(GrizzlyRequest request, GrizzlyResponse response) { try { String uri = request.getRequestURI(); String urlContext = contextPath + uri; File file = new File(urlContext); if (file.isDirectory()) { file = new File(urlContext + "/index.html"); } if (file.exists()) { FileReader fr = new FileReader(file); response.getWriter().println("Impleme bitdon de http"); response.setContentType(MediaType.TEXT_HTML); BufferedReader br = new BufferedReader(fr); while (br.ready()) { response.getWriter().println(br.readLine()); } } else { response.getWriter().println("404 connard"); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }, new String[] { "/" }); ws.start(); System.out.println("Grizzly start on port 8080 by jersey2"); System.out.println("Attention grizzly ne sert pas du html mais que des servlette"); System.out.println("use url: http://localhost:8080/Jersey1/WS/helloworld to get hello"); System.out.println("hit enter to stop"); Scanner sc = new Scanner(System.in); sc.nextLine(); System.out.println("Grizzly stop"); ws.stop();

Form

Exemple 1

Voici comment couplet un formullaire à Jersey

Form

<form action="http://localhost:8080/Jersey1/WS/Formu1" enctype="application/x-www-form-urlencoded" method="post" > First name: <input type="text" name="fname"><br> Last name: <input type="text" name="lname"><br> <input type="submit" value="Submit"> </form>

Java

package com.gadille.services; import java.io.IOException; import java.util.List; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MultivaluedMap; @Path("/Formu1") public class Form1 { //ok marche aussi @POST @Consumes("application/x-www-form-urlencoded") @Produces("text/plain") public String postLeads(MultivaluedMap formParams) throws IOException { System.out.println(formParams.toString()); List list=formParams.get("fname"); String fname=list.get(0); list=formParams.get("lname"); String lname=list.get(0); return ("First name "+fname+"\nLast name "+lname); } }

Exemple 2

Form

meme formullaire mais on appéle la class 2
<form action="http://localhost:8080/Jersey1/WS/Formu2" enctype="application/x-www-form-urlencoded" method="post" > First name: <input type="text" name="fname"><br> Last name: <input type="text" name="lname"><br> <input type="submit" value="Submit"> </form>

Java

package com.gadille.services; import java.io.IOException; import javax.ws.rs.Consumes; import javax.ws.rs.DefaultValue; import javax.ws.rs.FormParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("/Formu2") public class Form2 { @POST @Consumes("application/x-www-form-urlencoded") @Produces(MediaType.TEXT_HTML) public String postLeads(@FormParam("fname") @DefaultValue("???") String fname,@FormParam("lname") String lname) throws IOException { return ("your first name is: <b>,"+fname+"</b>,<br>,your surname is:"+lname); } }

File

Exemple 1

Cette exmple permet de charger un fichier sour forme de stream avec un client java (ou autre)

LoadFile1.java

package com.gadille.services; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.core.MediaType; @Path("/LoadFile1") public class LoadFile1 { private final static String DATA_DIR = "/tmp"; @POST @Consumes(MediaType.APPLICATION_OCTET_STREAM) public void postLeads(InputStream inputStream) throws IOException { // get/save file BufferedReader br = new BufferedReader(new InputStreamReader( inputStream)); PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter( new File(System.getProperty("user.home") + DATA_DIR + "/toto"), false))); String line; while ((line = br.readLine()) != null) { pw.println(line); } pw.close(); } }

TestGrizHttpClient.java (extract)

Un extrait de la class code dispos ici
System.getProperty("user.home") + DATA_DIR + "/toto" ceci represente l'emplacement du fichier sur le serveur
toto est son nom (on ne connais pas le nom d'origine)
public void postFile1() throws HttpException, IOException { System.out.println("postFile1 ==> Start"); // clean before test File resultFile = new File(System.getProperty("user.home") + DATA_DIR + "/toto"); if (resultFile.exists()) resultFile.delete(); // post PostMethod method = new PostMethod(URL_PREFIX + "LoadFile1"); method.setRequestHeader("Content-Type", MediaType.APPLICATION_OCTET_STREAM); File basedir = new File(System.getProperty("basedir", "")).getAbsoluteFile(); File file = new File(basedir, "src/test/resources/test.txt"); InputStream inputStream = new FileInputStream(file); method.setRequestEntity(new InputStreamRequestEntity(inputStream)); HttpClient client = new HttpClient(); try { client.executeMethod(method); assertEquals("Status code not valid", HttpServletResponse.SC_NO_CONTENT, method.getStatusCode()); } finally { method.releaseConnection(); } // verif if (resultFile.exists()) { System.out.println("File upload sucessfully"); } else { Assert.assertTrue("File not uploaded", false); } System.out.println("postFile1 ==> end ok"); }

Exemple 2

LoadFile2.java

Recuperation d'un param paser dans l'url
package com.gadille.services; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.MediaType; @Path("/LoadFile2/{country}") public class LoadFile2 { private final static String DATA_DIR = "/tmp"; @POST @Consumes(MediaType.APPLICATION_OCTET_STREAM) public void postLeads(@PathParam("country") String country, InputStream inputStream) throws IOException { //country System.out.println("Country:"+country); // get/save file BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(new File(System.getProperty("user.home") + DATA_DIR+"/"+country+".txt"), false))); String line; while ((line = br.readLine()) != null) { pw.println(line); } pw.close(); } }

TestGrizHttpClient.java (extract)

@Test public void postFile2() throws HttpException, IOException { System.out.println("postFile2 ==> Start (+ country en url)"); // clean before test File resultFile = new File(System.getProperty("user.home") + DATA_DIR + "/uk.txt"); if (resultFile.exists()) resultFile.delete(); PostMethod method = new PostMethod(URL_PREFIX + "LoadFile2/uk"); method.setRequestHeader("Content-Type", MediaType.APPLICATION_OCTET_STREAM); // method.setRequestHeader("Content-Encoding", "gzip"); File basedir = new File(System.getProperty("basedir", "")).getAbsoluteFile(); File file = new File(basedir, "src/test/resources/test.txt"); InputStream inputStream = new FileInputStream(file); method.setRequestEntity(new InputStreamRequestEntity(inputStream)); HttpClient client = new HttpClient(); try { client.executeMethod(method); assertEquals("Status code not valid", HttpServletResponse.SC_NO_CONTENT, method.getStatusCode()); } finally { method.releaseConnection(); } // verif if (resultFile.exists()) { System.out.println("File upload sucessfully"); } else { Assert.assertTrue("File not uploaded", false); } System.out.println("postFile2 ==> end ok"); }

Exemple 3

LoadFile3.java

Recuperation d'un param paser comme argument dans un multipart/form-data
package com.gadille.services; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import com.sun.jersey.multipart.BodyPartEntity; import com.sun.jersey.multipart.MultiPart; @Path("/LoadFile3") public class LoadFile3 { private final static String DATA_DIR = "/tmp"; @POST @Consumes("multipart/form-data") public void postForm1(MultiPart multiPart) throws IOException, InterruptedException { String country = multiPart.getBodyParts().get(0).getEntityAs(String.class); // get the second part BodyPartEntity bpe = (BodyPartEntity) multiPart.getBodyParts().get(1).getEntity(); InputStreamReader is = new InputStreamReader(bpe.getInputStream()); BufferedReader br = new BufferedReader(is); // get/save file PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(new File(System.getProperty("user.home")+DATA_DIR +"/"+ country + ".txt"), false))); String line; do{ line = br.readLine(); System.out.println(line); if (line!=null){ pw.println(line); } }while (br.ready()) ; pw.close(); } }

TestGrizHttpClient.java (extract)

@Test public void postFile3() throws HttpException, IOException { System.out.println("postFile3 ==> Start (multipart country)"); // clean before test File resultFile = new File(System.getProperty("user.home") + DATA_DIR + "/uk.txt"); if (resultFile.exists()) resultFile.delete(); //test PostMethod pm = new PostMethod(URL_PREFIX + "LoadFile3"); String basedir = System.getProperty("basedir", ""); File file = new File(basedir + "src/test/resources/test.txt"); ArrayList arrayList = new ArrayList(); arrayList.add(new StringPart("country", "uk")); arrayList.add(new FilePart("test", file)); MultipartRequestEntity mre = new MultipartRequestEntity(arrayList.toArray(new Part[] {}), pm.getParams()); pm.setRequestEntity(mre); HttpClient client = new HttpClient(); try { client.executeMethod(pm); assertEquals("Status code not valid", HttpServletResponse.SC_NO_CONTENT, pm.getStatusCode()); } finally { pm.releaseConnection(); } // verif if (resultFile.exists()) { System.out.println("File upload sucessfully"); } else { Assert.assertTrue("File not uploaded", false); } System.out.println("postFile3 ==> end ok"); }

Pour charger le fichier avec un formullaire

Country:
Choose your file:
<form action="http://localhost:8080/Jersey1/WS/LoadFile3" enctype="multipart/form-data" method="post"> Country: <input type="text" name="cc"/><br> Choose your file:<input type="file" name="file"/><br> <input type="submit" value="Send" /> <input type="reset"> </form>

Help Probleme et soluce

JerseyThe ResourceConfig instance does not contain any root resource classes.
Mon probleme venez d'un test qui ne passé pas donc je n'avais pas de class compiller dans le tomcat en sortie