【发布时间】:2015-01-08 23:16:06
【问题描述】:
我从一个以 JSON 格式消费和生成输出的服务开始。我使用 resteasy-jackson-provider 进行(去)编组,它从类描述中获取信息。过了一会儿,我被要求将 XML 添加为 MediaType。所以我用 JAXB 注释对我的 DTO 进行了注释,并添加了 resteasy-jaxb-provider。结果,我观察到生成的 JSON 输出来自与原始格式不同的 JAXB 注释。
我使用的是 RestEasy 版本 3.0.4。如上所述,我使用以下提供程序
- resteasy-jackson-provider
- resteasy-axb-provider。
- resteasy-jettison-provider,因为我将 RestEasy 集成到 Spring 中,并且这个提供者是一个传递依赖。
当我意识到这个问题时
- 将
XmlElementWrapper用于列表和何时 -
我写了一个自定义的
XmlAdapter,它序列化了一个复杂的数据结构Map<String, List<String>>。带有 XML MediaType 的请求很好。带有 JSON MediaType 的请求会导致异常。 Jackson 似乎利用XmlAdapter获取更多信息。这不是以前的情况。 Jackson 能够在没有 JAXB 注释的情况下编组 Map。org.codehaus.jackson.map.exc.UnrecognizedPropertyException:无法识别的字段“customer”(类 x.y.z.OptionalParametersMapType),未标记为可忽略 在 [来源:org.apache.catalina.connector.CoyoteInputStream@77119553;行:1,列:131](通过引用链:x.y.z.Request["optional"]->x.y.zOptionalParametersMapType["customer"] ) 在 org.codehaus.jackson.map.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:53) 在 org.codehaus.jackson.map.deser.StdDeserializationContext.unknownFieldException(StdDeserializationContext.java:267) 在 org.codehaus.jackson.map.deser.std.StdDeserializer.reportUnknownProperty(StdDeserializer.java:673) 在 org.codehaus.jackson.map.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:659) 在 org.codehaus.jackson.map.deser.BeanDeserializer.handleUnknownProperty(BeanDeserializer.java:1365) 在 org.codehaus.jackson.map.deser.BeanDeserializer._handleUnknown(BeanDeserializer.java:725) 在 org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:703) 在 org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580) 在 org.codehaus.jackson.xc.XmlAdapterJsonDeserializer.deserialize(XmlAdapterJsonDeserializer.java:59) 在 org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:299) 在 org.codehaus.jackson.map.deser.SettableBeanProperty$FieldProperty.deserializeAndSet(SettableBeanProperty.java:579) 在 org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:697) 在 org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580) 在 org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:2704) 在 org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1315) 在 org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:419)
那么,如何防止 RestEasy 使用 JAXB 注释来编组到 JSON 和从 JSON 中提取?
这里是请求类:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "domainRecommendationRequest")
public class Request {
@XmlJavaTypeAdapter(OptionalParametersXmlAdapter.class)
private Map<String, List<String>> optional = new HashMap<>();
}
这里是 XmlAdapter:
@Override
public class OptionalParametersXmlAdapter extends XmlAdapter<OptionalParametersMapType, Map<String, List<String>>> {
public OptionalParametersMapType marshal(Map<String, List<String>> v) throws Exception {
OptionalParametersMapType result = new OptionalParametersMapType();
List<OptionalParameterItemType> optionalParameterItemTypes = new ArrayList<>();
Set<String> keySet = v.keySet();
for (String parameterName : keySet) {
OptionalParameterItemType item = new OptionalParameterItemType();
item.name = parameterName;
item.values = v.get(parameterName);
optionalParameterItemTypes.add(item);
}
result.parameter = optionalParameterItemTypes;
return result;
}
}
这是地图的包装:
public class OptionalParametersMapType {
public List<OptionalParameterItemType> parameter = new ArrayList<>();
}
这是实际的地图条目:
public class OptionalParameterItemType {
@XmlAttribute
public String name;
@XmlElementWrapper(name = "values")
@XmlElement(name = "value")
public List<String> values = new ArrayList<>();
}
这是我对 JSON 请求的期望:
{"optional":{"customer":["Mike"]}}
如您所见,我确实打算在 XML 中使用不同的格式。
【问题讨论】:
标签: json jaxb jax-rs marshalling resteasy