コントラクトに定期的に要素を追加できる Web サービスを呼び出します。
例: 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 から) で生成されます。
ここで、SOAP 応答に新しい要素が表示された場合に備えて、Bean をフォールト トレラントにするソリューションがあるかどうかを知りたいと思います。
<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)を確認しましたが、ドキュメント(およびGoogle)には何も見つかりませんでした。アンマーシャリング操作は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;
}
更新:この投稿を見ましたが、私の気持ちは同じでした: JAXB は、CXF なしで単独で使用された場合、マップされていない要素を無視します。を使用することによりcxf-codegen-plugin
、そうではありません。