我正在使用Jersey 2.17和Moxy,我的功能如下:
@Produces(APPLICATION_JSON)
@Restricted
public List<User> getFriends(
@PathParam("user") String user
) {
return userDAO.getFriends(user);
}
User.preferences是HashMap
。
几乎所有对象都可以正常工作,除了HashMap
被转换为:
&#34;偏好&#34; {&#34;条目&#34;:[{&#34;键&#34; {&#34;类型&#34;:&#34;串&#34 ;,&#34;值&#34;:&#34;语言&#34;}&#34;值&#34; {&#34;类型&#34;:&#34;串&#34;,& #34;值&#34;:&#34;恩&#34;}},{&#34;键&#34; {&#34;类型&#34;:&#34;串&#34;&# 34;值&#34;:&#34;国家&#34;}&#34;值&#34; {&#34;类型&#34;:&#34;串&#34;&#34;值& #34;:&#34; US&#34;}}]}
但我真正想要返回的只是一个javascript对象,如:
首选项:{&#34;语言&#34;:&#34;恩&#34;&#34;国家&#34;:&#34; US&#34;}
我该怎么做?
答案 0 :(得分:9)
是的MOXy和地图不能很好地运作。令人遗憾,因为JSON只不过是映射键/值对。如果您想使用MOXy,则需要使用XmlAdapter
。在这种情况下,您希望JSON的方式,您将需要创建一个具有所有可能的首选项的名称的类型(类)。任意键值对应采用您需要的形式,但由于MOXy无法制作地图,因此您需要将其映射到您自己的类型。例如
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;
}
}
你的DTO
@XmlRootElement
public class User {
@XmlJavaTypeAdapter(PreferencesAdapter.class)
public HashMap<String, String> preferences;
}
但是,如果我们要做所有这些,为什么我们不首先使用Preferences
对象而不是Map
?这是一个修辞问题。我完全明白你为什么不这样做。但这是MOXy的局限之一,因为它让JAXB陷入困境,而JAXB从来没有与Map很好地合作,这很可悲,就像我说的那样,JSON实际上只不过是关键值的映射
由于这个原因,以及我过去遇到的其他许多其他人,我建议不要使用MOXy,即使它是泽西岛推荐的。相反,使用杰克逊。杰克逊一直是JSON处理的事实上的Java goto。对杰克逊来说,只需使用这种依赖
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
</dependency>
如果您取消了MOXy依赖项,这个Jackson模块应该可以解决问题。否则,如果您保留MOXy依赖关系,则需要注册JacksonFeature