如何使用Moxy和Jersey从HashMap返回JSON对象

我使用Jersey 2.17和Moxy,我有以下function:

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

User.preferences是一个HashMap

它适用于几乎所有对象,除了HashMap ,它被翻译成:

“偏好”:{ “条目”:[{ “键”:{ “类型”: “串”, “值”: “语言”}, “值”:{ “类型”: “串”, “值”: “恩”}},{ “关键”:{ “类型”: “串”, “值”: “国”}, “值”:{ “类型”: “串”, “值”: “US”} }]}

但我真的想要返回的只是一个javascript对象,如:

喜好:{ “语言”: “恩”, “国”: “US”}

我怎样才能做到这一点?

是的MOXy和地图不能很好地工作。 这很难过,因为JSON只不过是映射键/值对。 如果要使用MOXy,则需要使用XmlAdapter 。 在这种情况下,您希望JSON的方式,您将需要创建一个具有所有可能的首选项的名称的类型(类)。 任意键值对应采用您需要的forms,但由于MOXy无法执行地图,因此您需要将其映射到您自己的类型。 例如

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

你的DTO

 @XmlRootElement public class User { @XmlJavaTypeAdapter(PreferencesAdapter.class) public HashMap preferences; } 

但是如果我们要做所有这些,为什么我们不首先使用Preferences对象而不是Map ? 这是一个修辞问题。 我完全明白你为什么不这样做。 但这是MOXy的局限之一,因为它让我们对JAXB有了很大的帮助,而JAXB从来没有与Map很好地合作,这很可悲,就像我说的那样,JSON实际上只不过是一个关键值的映射。

出于这个原因,以及我过去遇到的其他许多其他人,我建议不要使用MOXy,即使它是泽西岛推荐的。 相反,使用jackson。 jackson已成为JSON处理的事实Java goto一段时间了。 对jackson来说,只需使用这种依赖

  org.glassfish.jersey.media jersey-media-json-jackson ${jersey.version}  

如果你取出了MOXy依赖项,这个Jackson模块应该可以解决问题。 否则,如果您保留MOXy依赖关系,则需要注册JacksonFeature