我调用了一个网络服务,它可以定期在他们的合同中添加一些元素。
示例:SOAP 响应正文包含:
<picture>
<active>true</active>
<code>172</code>
<label>Nikon D3200 Black</label>
<downloadEnabled>true</downloadEnabled>
</picture>
<picture>
<active>false</active>
<code>177</code>
<label>Nikon D5200 Red</label>
<downloadEnabled>true</downloadEnabled>
<extraField>none</extraField>
</picture>
我的 CXF 生成的 JAXB Bean 看起来像这样:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "pictureListJAXB", propOrder = {
"active",
"code",
"label",
"downloadEnabled",
"extraField"
})
public class PictureListJAXB {
protected boolean active;
protected String code;
protected String label;
protected boolean downloadEnabled;
@XmlElement(nillable = true)
protected String extraField
// And Getters / Setters comes here after
}
JAXB bean 是使用 maven 插件cxf-codegen-plugin
版本 2.6.2(来自 apache.cxf)生成的。
现在我想知道是否有一种解决方案可以让我的 Bean 在 SOAP 响应中出现新元素时具有容错性:
<picture>
<active>true</active>
<code>172</code>
<label>Nikon D3200 Black</label>
<downloadEnabled>true</downloadEnabled>
<newUnmappedElement>anything irrelevant</newUnmappedElement>
</picture>
现在,当我收到这样的回复时,我得到了一个Unmarshalling Error
因为这个新元素。
我的 JAXB 包含我想要管理的最小字段,但我希望 bean 能够处理新元素并忽略它们。
有没有办法在不重新生成 JAXB Bean 的情况下做到这一点?(现在我必须重新生成 Bean 并发布我的项目)
我检查了 CXF 选项(和 xjc),但在文档(和谷歌)中一无所获。解组操作也是在ReferentialService
CXF 生成的中自动完成的,然后一个选项来修改这部分的生成就足够了。
以下是使用 CXF 生成的类调用 Web 服务的代码:
public ReferentialService getReferentialService(String resource, String auth) throws RuntimeException {
// These two classes are generated by CXF
Referential referential;
ReferentialService referentialService;
// Get the resource URL in form http://myserver:port/remote-backend/resource?wsdl
referential = new Referential(new URL(MyConfigUtil.getWSDL(resource)));
referentialService = referential.getReferentialServicePort();
BindingProvider bp = (BindingProvider) referentialService;
// Get the endpoint URL in form http://myserver:port/remote-backend/resource
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, MyConfigUtil.getWebServiceEndPoint(resource));
// Add SOAP credentials
String username = HttpBasicAuthHelper.getUsername(auth);
String password = HttpBasicAuthHelper.getPassword(auth);
bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, username);
bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);
return referentialService;
}
和电话:
// Throws Exception just for the sample code
public InputStream listPictures(QueryDTO request, String resource, String auth) throws Exception {
InputStream is = null;
if (request != null) {
// This is the WS Call which failed with unmarshal error
List<PictureListJAXB> result = getReferentialService(resource, auth).getPictures(request);
// Some code to convert JAXB into a XML stream
is = convertObjectToXmlStream(result);
}
return is;
}
更新:我看到了这篇文章,我的感觉是一样的:如果在没有 CXF 的情况下单独使用,JAXB 将忽略未映射的元素。通过使用cxf-codegen-plugin
,情况并非如此。