Apache Tomcat est sans doute le serveur d’applications le plus couramment utilisé pour les applications WebApp métiers. Mais, de base, c’est un serveur de servlet / JSP. Apache TomEE, lui, propose bien plus.
CDI, Contexts and Dependency Injection
Sans CDI, ils est difficile aujourd’hui de développer une application Java. Tomcat requière l’intégration d’un ou plusieurs frameworks tandis que TomEE est livré avec Apache OpenWebBeans.
JPA, Java Persistence API
Sans JPA, l’accès à une base de données est tout simplement un enfer (sans parler des correctifs et des évolutions). Tomcat est livré nu alors que TomEE fournit Apache OpenJPA.
JAX-RS, Java RESTful Web Services
Une webapp sans REST ne serait pas la panacée. Tomcat ne prévoit rien mais TomEE livre Apache CXF.
JSON (Binding & Processing)
Faire du REST sans JSON, c’est se compliquer pas mal la vie. Tomcat nécessite d’ajouter des librairies, Tomee amène JSON-B & JSON-P.
JAAS, Java Authentication & Authorization
Une couche de sécurité ne saurait nuire. Alors que Tomcat ne prévoit rien, TomEE l’amène de base.
Autres bonus
- La taille du fichier WAR est méchamment réduite car il n’y a aucune dépendances à ajouter pour profiter des possibilités évoquées plut tôt.
- On évite Spring car TomEE dispose de tout le nécessaire.
- Évidemment la mise à jour des librairies se fait en changeant de version de TomEE, ça réduit un peu la course aux nouvelles versions.
Exemple
J’ai écrit un exemple de test “tout pourri” pour montrer la facilité à créer un Web Service REST.
pom.xml
1<?xml version="1.0" encoding="UTF-8"?>
2
3<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 <modelVersion>4.0.0</modelVersion>
6
7 <groupId>ch.gtg.test</groupId>
8 <artifactId>apache</artifactId>
9 <version>1.0-SNAPSHOT</version>
10 <packaging>war</packaging>
11
12 <name>Apache Test Webapp</name>
13 <url>https://www.gobothegeek.ch</url>
14
15 <properties>
16 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
17 <maven.compiler.source>1.7</maven.compiler.source>
18 <maven.compiler.target>1.7</maven.compiler.target>
19 </properties>
20
21 <dependencies>
22 <dependency>
23 <groupId>org.apache.tomee</groupId>
24 <artifactId>javaee-api</artifactId>
25 <version>8.0</version>
26 <scope>provided</scope>
27 </dependency>
28 </dependencies>
29
30 <build>
31 <finalName>testApache</finalName>
32 <plugins>
33 <plugin>
34 <groupId>org.apache.maven.plugins</groupId>
35 <artifactId>maven-compiler-plugin</artifactId>
36 <version>3.8.1</version>
37 <configuration>
38 <source>11</source>
39 <target>11</target>
40 </configuration>
41 <executions>
42 <execution>
43 <goals>
44 <goal>compile</goal>
45 </goals>
46 </execution>
47 </executions>
48 </plugin>
49 <plugin>
50 <groupId>org.apache.maven.plugins</groupId>
51 <artifactId>maven-war-plugin</artifactId>
52 <version>3.3.1</version>
53 <configuration>
54 <webXml>src/main/webapp/WEB-INF/web.xml</webXml>
55 <webResources>
56 <resource>
57 <directory>src/main/webapp/</directory>
58 <includes>
59 <include>**/*</include>
60 </includes>
61 </resource>
62 </webResources>
63 <outputDirectory>/opt/tomee8/webapps/</outputDirectory>
64 </configuration>
65 </plugin>
66 </plugins>
67 </build>
68</project>
Oui, tu as bien lu, il n’y a qu’une dépendance et elle ne sera pas inclue dans le WAR.
WEB-INF/web.xml
Ici, rien de spécial, pas de bootstrapping de servlet pour initialiser l’application ou rediriger vers les Web Services.
WEB-INF/beans.xml
Difficile de faire plus court.
TestApp.java
1package ch.gtg.test;
2
3import ch.gtg.test.TestCrud;
4import javax.ws.rs.ApplicationPath;
5import javax.ws.rs.core.Application;
6import java.util.Arrays;
7import java.util.HashSet;
8import java.util.Set;
9
10@ApplicationPath("/crud")
11public class TestApp extends Application {
12 public TestApp() { }
13
14 public Set<Class<?>> getClasses() {
15 return new HashSet<>(Arrays.asList(
16 TestCrud.class
17 ) );
18 }
19}
Ici on définit le point d’entrée des Web Services (/crud)
TestCrud.java
1package ch.gtg.test;
2
3import ch.gtg.test.TestModel;
4import ch.gtg.test.TestService;
5import javax.ejb.Singleton;
6import javax.inject.Inject;
7import javax.ws.rs.GET;
8import javax.ws.rs.Path;
9import javax.ws.rs.Produces;
10import javax.ws.rs.core.MediaType;
11import javax.ws.rs.core.Response;
12
13@Singleton
14@Path("/test")
15public class TestCrud {
16 @Inject private TestService testService;
17
18 @Path("/read")
19 @Produces( { MediaType.APPLICATION_JSON } )
20 @GET
21 public Response read() {
22 TestModel tm = new TestModel(this.testService.lowerMe("ABC"), "DEF");
23 return Response.status(Response.Status.OK).entity(tm).build();
24 }
25}
Dans cette classe on défini un Web Service REST accessible par l’url /test, avec une méthode accessible par l’url /read.
TestService.java
Ici, la méthode retourne le String en minuscules.
TestModel.java
1package ch.gtg.test;
2
3import java.util.Objects;
4
5public class TestModel {
6 private String test1;
7 private String test2;
8
9 public TestModel() { }
10
11 public TestModel(String test1, String test2) {
12 this.test1 = test1;
13 this.test2 = test2;
14 }
15
16 public String getTest1() { return test1; }
17 public void setTest1(String test1) { this.test1 = test1; }
18
19 public String getTest2() { return test2; }
20 public void setTest2(String test2) { this.test2 = test2; }
21
22 @Override
23 public boolean equals(Object o) {
24 if (this == o) return true;
25 if (o == null || getClass() != o.getClass()) return false;
26 TestModel testModel = (TestModel) o;
27 return Objects.equals(test1, testModel.test1) && Objects.equals(test2, testModel.test2);
28 }
29
30 @Override
31 public int hashCode() {
32 return Objects.hash(test1, test2);
33 }
34
35 @Override
36 public String toString() {
37 return "ReadModel{" +
38 "test1='" + test1 + '\'' +
39 ", test2='" + test2 + '\'' +
40 '}';
41 }
42}
Rien d’exceptionnel, ici on a une entity avec deux champs.
En appelant l’url http://localhost/testApache/crud/test/read, on obtient un beau JSON:
Conclusion
Avec TomEE, Apache fournit un serveur applicatif qui conserve la qualité et la fiabilité d’un Tomcat et lui ajoute les frameworks utiles pour un gain de productivité et de souplesse vraiment bienvenue.