La façon de renvoyer un Map
en tant que document XML/JSON en utilisant le framework Jersey/JAX-RS n'est pas si évidente. Il prend déjà en charge List
s, mais quand il s'agit de Map
s, il n'y a pas de MessageBodyWriter
. Et même si je devais intégrer le Ma
dans une classe wrapper, il n'y a pas de type map
dans le schéma XML.
Des conseils pratiques sur la façon de marshaler une carte dans un document XML/JSON à Jersey?
Je sais qu'il est très tard pour répondre, mais j'espère que cela aidera quelqu'un un jour :) La solution la plus simple et la plus rapide que j'ai appliquée est
@GET
@Path("/{messageId}")
@Produces(MediaType.APPLICATION_JSON)
public Response getMessage(@PathParam("messageId") long id) {
Map<String, String> map = new HashMap<>();
map.put("1", "abc");
map.put("2", "def");
map.put("3", "ghi");
return Response.status(Status.OK).entity(map).build();
}
Sortie: {"1": "abc", "2": "def", "3": "ghi"}
Cela devrait certainement vous aider à résoudre votre problème.
Il est très facile de le faire dans Java EE 7.
La classe de ressources REST:
package com.mycompany.maptojson.rest;
import Java.util.HashMap;
import Java.util.Map;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.enterprise.context.RequestScoped;
@Path("maps")
@RequestScoped
public class MapToJson {
@GET
@Produces("application/json")
public Map getJson() {
Map<String, String> theMap = new HashMap<>();
theMap.put("foo", "bar");
return theMap;
}
}
Application
:
package com.mycompany.maptojson.rest;
import Java.util.Set;
import javax.ws.rs.core.Application;
@javax.ws.rs.ApplicationPath("webresources")
public class ApplicationConfig extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new Java.util.HashSet<>();
// following code can be used to customize Jersey 2.0 JSON provider:
try {
Class jsonProvider = Class.forName("org.glassfish.jersey.jackson.JacksonFeature");
// Class jsonProvider = Class.forName("org.glassfish.jersey.moxy.json.MoxyJsonFeature");
// Class jsonProvider = Class.forName("org.glassfish.jersey.jettison.JettisonFeature");
resources.add(jsonProvider);
} catch (ClassNotFoundException ex) {
Java.util.logging.Logger.getLogger(getClass().getName()).log(Java.util.logging.Level.SEVERE, null, ex);
}
addRestResourceClasses(resources);
return resources;
}
private void addRestResourceClasses(Set<Class<?>> resources) {
resources.add(com.mycompany.maptojson.rest.MapToJson.class);
}
}
Comme vous pouvez le voir, vous pouvez configurer différentes classes comme jsonProvider
:
Class.forName("org.glassfish.jersey.jackson.JacksonFeature");
ou
Class.forName("org.glassfish.jersey.moxy.json.MoxyJsonFeature");
ou
Class.forName("org.glassfish.jersey.jettison.JettisonFeature");
Je sais que cela fait déjà un moment, mais peut-être que quelqu'un le trouvera utile.
J'ai un problème similaire et pour moi il semble que seul Jackson supporte actuellement ce type de mappage direct de Map en JSON.
Dans Jersey , c'est aussi simple que de renvoyer la carte à partir de la méthode des ressources:
@Path("myResource")
public class MyResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Map<String, String> getMap() {
Map<String, String> map = new HashMap<String, String>();
map.put("some key", "some value");
return map;
}
}
et y accéder depuis le client en tant que:
// ... (client initialization)
Map<String, String> map = client.target().path("myResource").request("application/json").get(Map.class);
Avec Jackson (par opposition à MOXy ), vous devez enregistrer le JacksonFeature
manuellement, par exemple dans votre javax.ws.rs.core.Application
sous-classe (ou ResourceConfig
dans Jersey ):
public class MyApp extends ResourceConfig {
public MyApp() {
super(MyResource.class, JacksonFeature.class);
}
}
Et assurez-vous d'avoir le module Jersey Jackson sur classpath. Dans maven, ajoutez simplement:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>...</version>
</dependency>
sans maven, il pourrait être un peu plus compliqué d'ajouter toutes les dépendances. Et c'est tout, cela devrait fonctionner. Au moins avec Jackson provider.
Cela n'a pas fonctionné pour moi dans Jettison et id ne fonctionne pas dans MOXy encore (il y a un problème ouvert).
J'espère que cela t'aides.
Par défaut, Jersey utilise le fournisseur MOXy XML/JSON. Donc, si vous souhaitez utiliser MOXy, vous devez ajouter un adaptateur séparé. La solution simple est de supprimer la dépendance MOXy de pom.xml et d'ajouter la dépendance Jackson. Jackson s'occupera de tout.
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>{latest version}</version>
</dependency>
Désolé, je ne sais pas pourquoi MOXy est le fournisseur par défaut de Jeresey.
public class BeanClass{
private int duration, Id;
private String description;
private User user = new User();
Map<String, String> map = new HashMap<>();
}
@GET
@Produces({ MediaType.APPLICATION_JSON }) // , MediaType.APPLICATION_XML
public Response getAll() {
List<BeanClass> lstBean = ...
return Response.ok().entity(lstBean).build();
}
Merci,
La solution qui a fonctionné pour moi (Utilisation de largage):
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getJson() {
Map<String, String> testMap = new HashMap<>();
testMap.put("Key1", "value1");
testMap.put("key2", "value2");
JSONObject obj = new JSONObject(testMap);
return Response.status(200).entity(obj).build();
}