Accès à Jackson Object Mapper dans RestEasy

on m'a demandé d'embellir Jackson JSON par défaut à partir d'un point final RestEasy. J'ai fait quelques recherches sur Jackson et j'ai écrit du code autonome pour pouvoir supprimer les nulls, personnaliser les formats de données, etc. Maintenant le défi est d'injecter ce code dans la sérialisation JSON de RestEasy.

a en juger par les billets du forum c'est trivial au printemps, cependant ça ne semble pas être le cas en RestEasy. J'ai écrit un ContextResolver et configuré comme resteasy.fournisseur de contexte params dans Web.xml (sur Tomcat) mais qui empêche le webapp de charger sur Tomcat.

maintenant j'essaie d'étendre javax.ws.rs.noyau.Application et fournir un Contexterésolver mais ne faisant aucun progrès. Est-ce normal, quelqu'un a fait cela? Toute aide est grandement appréciée.

24
demandé sur Daniel Serodio 2011-12-14 05:08:03

6 réponses

Ok, j'ai compris, j'ai pu le faire en écrivant un JacksonJsonProvider personnalisé basé sur le Jackson FAQ: JAX-RS.Le code est comme suit:

@Provider
public class QBOJacksonJsonProvider extends JacksonJsonProvider {
    public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

    @Override
    public void writeTo(Object value, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String,Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
        Log.info(getClass(), "In custom JSON provider");
        //get the Object Mapper
        ObjectMapper mapper = locateMapper(type, mediaType);
        // Suppress null properties in JSON output
        mapper.getSerializationConfig().setSerializationInclusion(org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_NULL);
        // Set human readable date format
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
        mapper.getSerializationConfig().setDateFormat(sdf);

        super.writeTo(value, type, genericType, annotations, mediaType, httpHeaders, entityStream);
    }
}
14
répondu codegeek 2013-03-22 22:48:18

j'ai trouvé une meilleure façon de modifier la SerializationConfig de Jackson - vous pouvez intercepter la création ObjectMapper en utilisant un JAX-RS ContextResolver.

@Provider
@Produces(Array(MediaType.APPLICATION_JSON))
class JacksonConfig extends ContextResolver[ObjectMapper] {

  val mapper = new ObjectMapper()
  mapper.getSerializationConfig.setSerializationInclusion(Inclusion.NON_NULL)

  def getContext(objectType: Class[_]) = mapper
}

vous devez vous inscrire à RESTEasy de l'une des façons suivantes:

  • le retourner sous forme de classe ou d'instance à partir d'un javax.ws.rs.noyau.Application implementation
  • listez-le comme fournisseur de resteasy.les fournisseurs
  • laissez RESTEasy le scanner automatiquement dans votre guerre fichier. Voir Le Guide De Configuration
  • l'ajouter manuellement via ResteasyProviderFactory.getInstance().registerProvider(Class) or registerprovider instance (Object)

Référence: RESTEasy docs

Référence: Nicklas Karlsson sur les forums JBoss

Veuillez noter que cela fonctionne avec RESTEasy 2.3.2 livré avec un module dans JBoss 7.1.1.Final, mais ne semble pas fonctionner avec RESTEasy 3.0-beta5.

13
répondu James Baxter 2013-05-14 16:00:16

Fournisseur pour Jackson ObjectMapper devrait être la façon standard JAX-RS de faire cela (fonctionne avec Jersey), donc il semble que la façon d'aller avec RESTeasy aussi bien.

2
répondu StaxMan 2011-12-14 23:54:11

si vous utilisez le fournisseur Jackson2, vous devez faire quelque chose de légèrement différent de la réponse précédente. Cet exemple va Imprimer la sortie par défaut

@Provider
public class JSONProvider extends ResteasyJackson2Provider {

  @Override
  public void writeTo(Object value, Class<?> type, Type genericType, Annotation[]  annotations, MediaType json, MultivaluedMap<String, Object> headers, OutputStream body) throws IOException {

    ObjectMapper mapper = locateMapper(type, json);
    mapper.enable(SerializationFeature.INDENT_OUTPUT);

    super.writeTo(value, type, genericType, annotations, json, headers, body);
  }

}

et l'enregistrer dans votre web-xml, si vous n'avez pas autoregister, l'ajouter à votre resteasy.fournisseurs contexte-param

2
répondu Tadhg 2014-05-02 22:28:08

Si vous utilisez le Jackson 2.2.X fournisseur, Resteasy a fourni un impression d'annotation) des nouvelles à la une de JAXB fournisseur de:

org.jboss.resteasy.annotations.providers.jackson.Formatted

Voici un exemple:

@GET
@Produces("application/json")
@Path("/formatted/{id}")
@Formatted
public Product getFormattedProduct()
{
    return new Product(333, "robot");
}

comme l'exemple ci-dessus, l'annotation formatée par @activera sous-jacent à L'option Jackson " SerializationFeature.INDENT_OUTPUT".

© RESTEasy User Guide.

Ce n'est pas une solution globale, mais vous peut mettre l'annotation sur les classes trop.

0
répondu Vsevolod Golovanov 2017-05-04 20:42:25

j'ai eu beaucoup de travail pour l'enregistrer dans mon application, même en suivant le Conseil d'utiliser le context-param une fois que j'utilise la botte de printemps et n'ai pas le web.xml, voici ce que j'ai fait

fournisseur sur mesure

package com.mageddo;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider;

import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Provider;

@Provider
@Consumes({"application/json", "application/*+json", "text/json"})
@Produces({"application/json", "application/*+json", "text/json"})
public class CustomJacksonJsonProvider extends ResteasyJackson2Provider {

    private ObjectMapper objectMapper = new ObjectMapper(); // my own object mapper

    @Override
    public ObjectMapper locateMapper(Class<?> type, MediaType mediaType) {
        return objectMapper;
    }
}

S'inscrire sur demande

META-INF/services / javax.ws.rs.ext.Fournisseurs

com.mageddo.CustomJacksonJsonProvider
org.jboss.resteasy.plugins.providers.jackson.UnrecognizedPropertyExceptionHandler
0
répondu deFreitas 2018-07-11 17:14:45