java json jersey jersey-2.0 moxy

java - Cómo devolver un objeto JSON desde un HashMap con Moxy y Jersey



jersey-2.0 (1)

Sí, MOXy y Maps no funcionan bien. Es triste, ya que JSON no es más que pares de clave / valor mapeados. Si quiere usar MOXy, necesitará usar un XmlAdapter . En cuyo caso, de la forma en que desea el JSON, deberá crear un tipo (clase) que tenga el nombre de todas las preferencias posibles. Los pares de valores clave arbitrarios deben tener la forma que necesita, pero dado que MOXy no puede hacer mapas, deberá asignarlos a su propio tipo. Por ejemplo

public class PreferencesAdapter extends XmlAdapter<Preference, HashMap<String, String>> { @XmlRootElement public static class Preference { public String language; public String country; } @Override public HashMap<String, String> unmarshal(Preference p) throws Exception { HashMap<String, String> map = new HashMap<>(); map.put("language", p.language); map.put("country", p.country); return map; } @Override public Preference marshal(HashMap<String, String> v) throws Exception { Preference p = new Preference(); p.language = v.get("language"); p.country = v.get("country"); return p; } }

Su DTO

@XmlRootElement public class User { @XmlJavaTypeAdapter(PreferencesAdapter.class) public HashMap<String, String> preferences; }

Pero si estamos haciendo todo esto, ¿por qué no usamos un objeto Preferences en primer lugar en lugar de un Map ? Esa fue una pregunta retorica. Entiendo totalmente por qué no lo harías. Pero esta es una de las limitaciones de MOXy, ya que nos da mucha importancia a JAXB, y JAXB nunca ha jugado bien con Map, lo cual es triste, como dije, JSON no es más que un Map de valores clave. .

Por esta razón, y en realidad muchas otras que he encontrado en el pasado, no recomiendo usar MOXy a pesar de que Jersey lo recomienda. En cambio, usa Jackson. Jackson ha sido el goto de facto de Java para el procesamiento JSON durante un tiempo. Para Jackson, solo usa esta dependencia

<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jackson</artifactId> <version>${jersey.version}</version> </dependency>

Si elimina la dependencia de MOXy, este módulo Jackson debería funcionar de la caja. De lo contrario, si abandona la dependencia MOXy, deberá registrar JacksonFeature

Estoy usando Jersey 2.17 con Moxy y tengo funciones como:

@Produces(APPLICATION_JSON) @Restricted public List<User> getFriends( @PathParam("user") String user ) { return userDAO.getFriends(user); }

User.preferences es un HashMap .

Funciona bien para casi todos los objetos, excepto para un HashMap que se traduce en:

"preferencias": {"entrada": [{"clave": {"tipo": "cadena", "valor": "idioma"}, "valor": {"tipo": "cadena", "valor": "en"}}, {"key": {"type": "string", "value": "country"}, "value": {"type": "string", "value": "US"} }]}

pero lo que realmente me gustaría devolver es solo un objeto javascript como:

preferencias: {"idioma": "en", "país": "EE. UU."}

¿Cómo puedo hacer eso?