Utilisation de Jackson ObjectMapper avec Jersey
Je suis en utilisant le Maillot de 2,4 à créer une simple interface REST qui sert un objet JSON. Mon problème est que je suis en train d'utiliser le fasterxml Jackson annotations pour contrôler la sortie et ce n'est pas de travail pour moi. J'ai mis des annotations dans ma classe d'haricot, mais ils sont ignorés.
Quand je créer explicitement un ObjectMapper et de l'utiliser pour stringify le haricot de Java, j'obtiens le résultat que je veux, qui respecte les Jackson annotations. Cependant, je préférerais que je n'ai pas à faire de cette étape, afin que ma classe de ressource peut simplement renvoyer le haricot le Jersey et le framework prend soin de stringifying.
J'ai essayé de résoudre ce à l'aide de la réponse de Personnalisé ObjectMapper avec Jersey 2.2 et 2.1 Jacksoncependant, cela ne semble pas fonctionner pour moi. Je vois que le ContextResolver est créé mais il n'est jamais appelé.
J'ai aussi passé de nombreuses heures à tenter de résoudre ce qui, apparemment, problème simple. J'ai dépouillé cette baisse à une très simple cas de test, ce qui est illustré ci-dessous. J'apprécierais un peu d'aide dans la résolution de ce.
Des ressources de la classe Java:
@Path("resource")
public class MainResource {
public static class Foobar {
@JsonIgnore
private String foo = "foo";
private String baa = "baa";
private Map<String, List<? extends Number>> map = new HashMap<>();
public Foobar() {
map.put("even", Arrays.asList(new Integer[] { 2, 4, 6, 8, 10 }));
map.put("odd", Arrays.asList(new Integer[] { 1, 3, 5, 7, 9 }));
map.put("float", Arrays.asList(new Float[] { 1.1F, 2.2F, 3.3F }));
}
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
public String getBaa() {
return baa;
}
public void setBaa(String baa) {
this.baa = baa;
}
@JsonAnyGetter
public Map<String, List<? extends Number>> getMap() {
return map;
}
public void setMap(Map<String, List<? extends Number>> map) {
this.map = map;
}
}
private ObjectMapper om = new ObjectMapper();
@GET
@Path("get-object")
@Produces(MediaType.APPLICATION_JSON)
public Foobar getObject() {
//In this method, I simply return the bean object but the WRONG JSON syntax is generated.
return new Foobar();
}
@GET
@Path("get-string")
@Produces(MediaType.APPLICATION_JSON)
public String getString() throws JsonProcessingException {
//This method returns the RIGHT JSON syntax but I don't want to have to explicitly use the ObjectMapper.
Foobar foobar = new Foobar();
return om.writeValueAsString(foobar);
}
}
web.xml:
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<module-name>sample</module-name>
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>ie.cit.nimbus.sample</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
POM dépendances:
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.4.1</version>
</dependency>
</dependencies>
source d'informationauteur jcstockdale
Vous devez vous connecter pour publier un commentaire.
MODIFIER: Ne pas utiliser le vieux approche en dessous de la comme il produit des bugs (au moins avec un appareil android, voir EDIT2 pour plus de détails). Comme de mes tests, Maillot v2.6 semble résoudre le problème avec le
@Provide
dont l'approche n'a pas fonctionné. J'ai été en mesure de le faire fonctionner avec ce simple fournisseur de:Donc merci de ne pas utiliser mon hack du dessous.
L'ANCIENNE APPROCHE
À l'aide de
n'a pas de travail pour moi (Jersey 2.4 & Jackson 2.3) et peut-être que cela est dû à un dans la jackson fournisseur de rapport de bogue dans le code où la
ContextResolver
doivent être enregistrés dansJacksonJsonProvider.java
(2.3rc1):Mais au moins, je ne peut pas accéder à https://jersey.dev.java.net/issues/show_bug.cgi?id=288donc je ne sais pas ce que ce bug est d'environ.
Mais j'ai trouvé une solution de contournement (un hack si vous le voulez). Juste étendre
JacksonJsonProvider
avec le bon d'annotation et de retourner votreObjectMapper
comme ceci:Pas besoin de faire tout ce qu'il enregistre lui-même (à vérifier avec le journal, il enregistre la première fois que vous accédez à un service rest json). C'est maintenant à travailler pour moi, pas très élégant, mais j'ai renoncé.
EDIT: à Utiliser avec prudence - Im confronté à un bug peut-être lié à ce hack: Android volley ne peut pas envoyer un POST/PUT demande avec un corps de requête, toujours à 400 le cadre, je vais enquêter et de faire rapport à mes résultats.
EDIT2: Ce hack, est en effet responsable d'un générique de 400 à chaque fois qu'une application Android avec de volley et de
OKHTTP
client essayé essayé de faire une requête POST ou PUT donc ne pas l'utiliser dans mon test jersey 2.6 semble résoudre ce problème de sorte que vous pouvez utiliser@Provide
approcheMalheureusement tout le monde fait ce beaucoup plus difficile qu'il doit être. Le Maillot de l'équipe dans sa sagesse, a décidé d'intégrer Jackson 1.9, de sorte que leurs trucs wont' vous aider.
Mais il était assez facile pour moi. Faites simplement ceci:
Maintenant, se DÉBARRASSER DE CE:
Puis dans votre web.xml modifier cette ligne:
:
Cela devrait le faire.
À l'aide de
Jersey 2.13
vous pouvez forcer le@Provider
d'utiliser le mêmeObjectMapper
ne devrait créer unObjectMapper
:Je l'utilise pour
@Autowire
dans monObjectMapper
pour générerjson-schema
documents à la volée.Il y a beaucoup de façons d'intégrer jackson avec Jax-rs Maillot de mise en œuvre.
Si vous jetez un oeil à Mkyong tutoriel: http://www.mkyong.com/webservices/jax-rs/json-example-with-jersey-jackson/
Il semble que vous devriez également passer le "POJOMappingFeature" -> vrai dans l'init params dans web.xml.
Je pense que cela fonctionne pour Maillot de 1,8
Si vous jetez un oeil à Maillot officiel de la documentation à la place:
https://jersey.java.net/nonav/documentation/latest/user-guide.html#json.jackson
Il semble que vous devriez met en œuvre un Jax-rs fournisseur et d'ajouter que fournisseur de ressources de votre application
Ils vous donner un exemple de comment faire cela
https://github.com/jersey/jersey/blob/2.4.1/examples/json-jackson/src/main/java/org/glassfish/jersey/examples/jackson/MyObjectMapperProvider.java
J'ai utilisé de cette façon et qui a résolu mes problèmes, et Jackson annotations sont correctement analysés par Jackson fournisseur.
Hors sujet, je vous suggère d'utiliser cette syntaxe dans votre bean pour initialiser la carte:
ajouter sur chaque modèle de la classe comme ceci
il a travaillé pour moi, mais j'ai utilisé codehus jackson pots