Support MVC Jersey

Jersey MVC Support

1. Vue d'ensemble

Jersey is an open-source framework for developing RESTFul Web Services.

En plus de servir d'implémentation de référence JAX-RS, il comprend également un certain nombre d'extensions pour simplifier davantage le développement d'applications Web.

Dans ce didacticiel,we’ll create a small example application that uses the Model-View-Controller (MVC) extension offered by Jersey.

Pour savoir comment créer une API avec Jersey, consultez cewrite-up here.

2. MVC à Jersey

Jersey contains an extension to support the Model-View-Controller (MVC) design pattern.

Tout d'abord, dans le contexte des composants Jersey, le modèle Controller from MVC correspond à une classe de ressources ou à une méthode.

De même, la vue correspond à un modèle lié à une classe de ressources ou à une méthode. Enfin, le modèle représente un objet Java renvoyé par une méthode de ressource (contrôleur).

To use the capabilities of Jersey MVC in our application, we first need to register the MVC module extension that we wish to use.

Dans notre exemple, nous allons utiliser le moteur de modèles Java populaireFreemarker. Il s'agit de l'un des moteurs de rendu pris en charge par Jersey avec lesMustache et les Java Server Pages (JSP) standard.

Pour plus d'informations sur le fonctionnement de MVC, reportez-vous à cetutorial.

3. Configuration de l'application

Dans cette section, nous allons commencer par configurer les dépendances Maven nécessaires dans nospom.xml.

Ensuite, nous verrons comment configurer et exécuter notre serveur à l'aide d'un simple serveurGrizzly intégré.

3.1. Dépendances Maven

Commençons par ajouter l'extension Jersey MVC Freemarker.

Nous pouvons obtenir la dernière version deMaven Central:


    org.glassfish.jersey.ext
    jersey-mvc-freemarker
    2.27

Nous aurons également besoin du conteneur de servlet Grizzly.

Encore une fois, nous pouvons trouver la dernière version dansMaven Central:


    org.glassfish.jersey.containers
    jersey-container-grizzly2-servlet
    2.27

3.2. Configurer le serveur

Pour utiliser la prise en charge des modèles Jersey MVC dans notre applicationwe need to register the specific JAX-RS features provided by the MVC modules.

Dans cet esprit, nous définissons une configuration de ressource personnalisée:

public class ViewApplicationConfig extends ResourceConfig {
    public ViewApplicationConfig() {
        packages("com.example.jersey.server");
        property(FreemarkerMvcFeature.TEMPLATE_BASE_PATH, "templates/freemarker");
        register(FreemarkerMvcFeature.class);;
    }
}

Dans l'exemple ci-dessus, nous configurons trois éléments:

  • Tout d'abord, nous utilisons la méthodepackages pour dire à Jersey de scanner le packagecom.example.jersey.server pour les classes annotées avec@Path.  Cela enregistrera nosFruitResource

  • Ensuite, nous configurons le chemin de base afin de résoudre nos modèles. Cela indique à Jersey de chercher dans les modèles/src/main/resources/templates/freemarker  pour Freemarker

  • Enfin, nous enregistrons la fonctionnalité qui gère le rendu Freemarker via la classeFreemarkerMvcFeature 

3.3. Lancer l'application

Voyons maintenant comment exécuter notre application Web. Nous utiliserons lesexec-maven-plugin pour configurer nospom.xml pour exécuter notre serveur Web intégré:


    org.codehaus.mojo
    exec-maven-plugin
    
        com.example.jersey.server.http.EmbeddedHttpServer
    

Compilons et exécutons maintenant notre application avec Maven:

mvn clean compile exec:java
...
Jul 28, 2018 6:21:08 PM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer] Started.
Application started.
Try out http://localhost:8082/fruit
Stop the application using CTRL+C

Accédez à l'URL du navigateur -http://localhost:8080/fruit. Voilà, la «page d'accueil des fruits!» S'affiche.

4. Modèles MVC

À Jersey, l'API MVC se compose de deux classes pour lier le modèle à la vue, à savoirViewable et@Template.

Dans cette section, nous expliquerons trois manières différentes d'associer des modèles à notre vue:

  • Utilisation de la classeViewable

  • Utilisation de la annotation@Template 

  • Comment gérer les erreurs avec MVC et les transmettre à un modèle spécifique

4.1. Utilisation deViewable dans une classe de ressources

Commençons par regarderViewable:

@Path("/fruit")
public class FruitResource {
    @GET
    public Viewable get() {
        return new Viewable("/index.ftl", "Fruit Index Page");
    }
}

In this example, the FruitResource JAX-RS resource class is the controller. L'instanceViewable encapsule le modèle de données référencé qui est un simpleString.

De plus, nous incluons également une référence nommée au modèle de vue associé -index.ftl.

4.2. Utilisation de@Template sur une méthode de ressource

There’s no need to use Viewable every time we want to bind a model to a template.

Dans cet exemple suivant, nous allons simplement annoter notre méthode de ressource avec@Template:

@GET
@Template(name = "/all.ftl")
@Path("/all")
@Produces(MediaType.TEXT_HTML)
public Map getAllFruit() {
    List fruits = new ArrayList<>();
    fruits.add(new Fruit("banana", "yellow"));
    fruits.add(new Fruit("apple", "red"));
    fruits.add(new Fruit("kiwi", "green"));

    Map model = new HashMap<>();
    model.put("items", fruits);
    return model;
}

Dans cet exemple, nous avons utilisé l'annotation@Template. Cela évite d'encapsuler notre modèle directement dans une référence de modèle viaViewable et rend notre méthode de ressource plus lisible.

Le modèle est maintenant représenté par la valeur de retour de notre méthode de ressource annotée - aMap<String, Object>. Ceci est passé directement au modèleall.ftl qui affiche simplement notre liste de fruits.

4.3. Gestion des erreurs avec MVC

Voyons maintenant comment gérer les erreurs à l'aide de l'annotation@ErrorTemplate:

@GET
@ErrorTemplate(name = "/error.ftl")
@Template(name = "/named.ftl")
@Path("{name}")
@Produces(MediaType.TEXT_HTML)
public String getFruitByName(@PathParam("name") String name) {
    if (!"banana".equalsIgnoreCase(name)) {
        throw new IllegalArgumentException("Fruit not found: " + name);
    }
    return name;
}

Generally speaking, the purpose of the @ErrorTemplate annotation is to bind the model to an error view. Ce gestionnaire d'erreurs se chargera de rendre la réponse lorsqu'une exception est levée pendant le traitement d'une requête.

Dans notre exemple simple d'API Fruit, si aucune erreur ne se produit pendant le traitement, le modèlenamed.ftl est utilisé pour rendre la page. Sinon, si une exception est déclenchée, le modèleerror.ftl est montré à l'utilisateur.

In this case, the model is the thrown exception itself. Cela signifie qu'à partir de notre modèle, nous pouvons appeler des méthodes directement sur l'objet d'exception.

Jetons un coup d'œil à un extrait de notre modèleerror.ftl pour mettre en évidence ceci:


    

Error - ${model.message}!

Dans notre dernier exemple, nous allons jeter un œil à un test unitaire simple:

@Test
public void givenGetFruitByName_whenFruitUnknown_thenErrorTemplateInvoked() {
    String response = target("/fruit/orange").request()
      .get(String.class);
    assertThat(response, containsString("Error -  Fruit not found: orange!"));
}

Dans l'exemple ci-dessus, nous utilisons la réponse de notre ressource de fruits. Nous vérifions que la réponse contient le message desIllegalArgumentException qui a été lancé.

5. Conclusion

Dans cet article, nous avons exploré l’extension MVC du framework Jersey.

Nous avons commencé par présenter le fonctionnement de MVC à Jersey. Nous avons ensuite examiné comment configurer, exécuter et configurer un exemple d’application Web.

Enfin, nous avons étudié trois manières d’utiliser les modèles MVC avec Jersey et Freemarker et la gestion des erreurs.

Comme toujours, le code source complet de l'article est disponibleover on GitHub.