SpringMVC 4, Rest & Test avec JSON Date Conversions (Jackson2)

springRest_logojackson2-logo-onlyjson

Le titre est déjà tout un programme ! L’objectif est d’illustrer avec plusieurs exemples les nouveautés Rest API dans Spring MVC 4 et en particulier sur le support Jackson2 dans Spring4.

Nous allons voir de quelle manière nous pouvons ignorer certains attributs de classe, puis comment filtrer certains champs dans les conversions/sérialisations Json (ou encore Xml). Les conversions (sérialisation et désérialisation) des dates seront également traitées.

Développer des services REST avec Spring 3 – Part 1/2

L’objet de cet article est de présenter les différentes options qui permettent d’exposer des services REST à l’aide de Spring MVC 3.2.

Spring propose deux approches pour exposer des services REST.

–  La première est basée sur les principes de fonctionnement du framework MVC de Spring, à savoir l’utilisation du ContentNegotiatingViewResolver.

–  La seconde, plus récente,  fait appel  aux HttpMessageConverters et à l’annotation @ResponseBody.

Méthode 1 : Utiliser le ContentNegotiatingViewResolver

L’utilisation du ContentNegotiatingViewResolver pour exposer des API Rest a été la première approche proposée car elle s’appuie sur le mécanisme de Spring MVC existant.

Pour rappel SpringMVC permet de définir des ViewResolver qui permettent de définir la manière dont seront affichées les données retournées par le Controller MVC.

La déclaration de la servlet Spring dans le XML est nécessaire:

<web-app>
   <servlet>
     <servlet-name>dispatchServlet</servlet-name>
     <servlet-class>
         org.springframework.web.servlet.DispatcherServlet
     </servlet-class>
   </servlet>

   <servlet-mapping>
      <servlet-name>disptachServlet</servlet-name>
      <url-pattern>/rest/*</url-pattern>
   </servlet-mapping>
 </web-app>

Dans le cas classique d’affichage d’une JSP, on utilise l’InternalViewResolver ( qui permet d’appeler une JSP pour afficher les données), que l’on déclare dans la configuration Spring :

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
   <property name="prefix" value="/WEB-INF/views/" />
   <property name="suffix" value=".jsp" />
</bean>

Note : La servlet de Spring (DispatcherServlet) référence les différents ViewResolver en parcourant les beans définis dans  la configuration Spring.

Lorsque vous utilisez le ContentNegotiatingViewResolver, votre controller web retourne un ModelView ou le nom d’une vue, et selon certains critères paramétrables, le ContentNegotiatingViewResolver va choisir la vue à utiliser pour retourner le résultat :

@Controller
@RequestMapping(value="/todo") 
public class TodoRestService2 { 
    @Autowired 
    private TodoService todoService; 

    @RequestMapping(value="/{id}", method= RequestMethod.GET) 
    public ModelAndView find(@PathVariable("id") Long id) { 
       Todo todo = todoService.find(id); 
       return new ModelAndView("todo", "todo", todo);
       }
 }

Pour l’exposition de service REST, Spring propose différentes implémentations de ces vues pour les formats de contenus les plus courants :

  • org.springframework.web.servlet.view.json.MappingJacksonJsonView : format de type Json.
  • org.springframework.web.servlet.view.xml.MarshallingView : format de type XML.
  • org.springframework.web.servlet.view.documentClass.AbstractPdfView : format de type Pdf.
  • etc…

Il est bien sur possible de créer des implémentations spécifiques ou d’étendre celles existant.

Les critères qui permettent au ContentNegotiatingViewResolver de choisir la bonne vue sont définis à l’aide de stratégies. Ces stratégies permettent de définir un lien entre l’url appelée par le client et le format de la réponse qui sera retournée.  La vue qui correspond au format sera alors appelée.

Spring fournit principalement les implémentations suivantes :

  • org.springframework.web.accept.PathExtensionContentNegotiationStrategy : Stratégie basée sur l’extension de l’url ( .json, .xml, .html…etc).
  • org.springframework.web.accept.ParameterContentNegotiationStrategy : Stratégie basée sur le passage d’un paramètre dans la requête.
  • org.springframework.web.accept.HeaderContentNegotiationStrategy : Stratégie basée sur l’analyse sur l’attribut « accept » du header de la requête.

Prenons l’exemple d’un service RESTFul  qui  permettrait de retourner le contenu d’un bean Java en XML ou en Json en fonction de l’extension de l’url.

Ci-dessous la configuration qui permet de le faire :

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
   <property name="contentNegotiationManager">
      <bean class="org.springframework.web.accept.ContentNegotiationManager">
      <constructor-arg>
        <bean
         class="org.springframework.web.accept.PathExtensionContentNegotiationStrategy">
          <constructor-arg>
           <map>
             <entry key="json" value="application/json"/>
             <entry key="xml" value="application/xml"/>
           </map>
          </constructor-arg>
         </bean>
       </constructor-arg>
      </bean>
   </property> 
<property name="defaultViews">
  <list>
    <!-- Renders JSON View -->
    <bean
     class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />

    <!-- Renders XML View -->
    <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
     <constructor-arg>
       <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
         <property name="packagesToScan">
            <list>
              <value>org.demo.domain</value>
            </list>
         </property>
      </bean>
     </constructor-arg>
    </bean>
  </list>
</property>
</bean>

Dans cet exemple, la stratégie PathExtensionContentNegotiationStrategy permet de définir qu’un appel vers une url finissant par .json sera dirigée vers la vue MappingJacksonJsonView car elle est capable de générer du contenu de type application/json.

Même chose avec les urls finissant par .xml et la vue MarshallingView.

Dans un second article nous étudierons la seconde solution qui consiste à utiliser des HttpMessageConverters.

Installation du projet Contacts

Pour ceux qui n’étaient pas à l’Ideo Bar (ouai j’ai les noms !! :) ), j’y ai présenté une application Contacts qui permet de mettre en oeuvre une partie serveur en Java EE 6, avec du JPA, des EJB 3 et des web service rest JAX-RS.

Cette application est désormais disponible sur mon GitHub : https://github.com/sebrevel/Contacts

Vous y trouverez bien entendu le code mais aussi une petite explication : https://github.com/sebrevel/Contacts/blob/master/README.md

et une doc d’installation qui comprend le clone du repo GitHub, la création du workspace IntelliJ et le déploiement sur un Glassfish : http://www.youtube.com/watch?v=NJpBY6ys-mE&feature=plcp

Amusez-vous bien :)

RESTer simple avec Spring et JAXB – Partie 2 : serveur REST avec Spring web

Ce billet fait suite au sujet portant sur le « Binding avec JAXB ».
Après avoir réaliser le binding du modèle métier grâce aux annotations JAXB, la partie serveur de l’application peut être réalisée.
La façon la plus simple de réaliser une communication entre applications est de passer par des standards.
Le style d’architecte REST (Representational State Transfer) utilise des standards qui ont fait la renommée du web :

  • HTTP comme protocole de communication,
  • URI comme syntaxe d’adressage des ressources,
  • XML, Json… comme syntaxe pour la représentation des données.