我在Moxy上使用Jersey 2.17,并且具有以下功能:
@Produces(APPLICATION_JSON) @Restricted public List<User> getFriends( @PathParam("user") String user ) { return userDAO.getFriends(user); }
User.preferences是一个HashMap。
HashMap
除了将a HashMap转换为:
“ preferences”:{“ entry”:[{“ key”:{“ type”:“ string”,“ value”:“ language”},“ value”:{“ type”:“ string”,“ value”: “ en”}},{“ key”:{“ type”:“ string”,“ value”:“ country”},“ value”:{“ type”:“ string”,“ value”:“ US”} }]}
但我真正想返回的只是一个JavaScript对象,例如:
偏好设置:{“ language”:“ en”,“ country”:“ US”}
我怎样才能做到这一点?
是的,MOXy和地图效果不佳。可悲的是,JSON只不过是映射的键/值对。如果要使用MOXy,则需要使用XmlAdapter。在这种情况下,您需要JSON的方式将需要创建一个具有所有可能的首选项名称的类型(类)。任意的键值对 应该 是您所需要的形式,但因为莫西不能做地图,您需要将其映射到自己的类型。例如
XmlAdapter
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却从未与Map很好地配合使用,这令人遗憾,就像我说的那样,JSON实际上仅是键值Map 。
Preferences
Map
因此,即使过去我也遇到过许多其他原因,即使泽西岛推荐使用MOXy,我也不建议使用。而是使用Jackson。杰克逊(Jackson)成为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
JacksonFeature