Есть сервер A и сервер B (soap). Сервер A отправляет запрос серверу B.
clubProWS.getClientLevel(requestContext.getShprefCode(), profileId.bigIntegerValue(), requestContext.getLocale(), resultHolder, clientLevelHolder);
@WebMethod(operationName = "GetClientLevel")
@RequestWrapper(localName = "GetClientLevel", targetNamespace = "http://sportmaster.ru/ws/ClubPro/UserGate/", className = "ru.sportmaster.esm.usergate.clubpro.soap.GetClientLevelRequest")
@ResponseWrapper(localName = "GetClientLevelResponse", targetNamespace = "http://sportmaster.ru/ws/ClubPro/UserGate/", className = "ru.sportmaster.esm.usergate.clubpro.soap.GetClientLevelResponse")
public void getClientLevel(
@WebParam(name = "idShprefSite", targetNamespace = "")
BigInteger idShprefSite,
@WebParam(name = "ClientRegCode", targetNamespace = "")
BigInteger clientRegCode,
@WebParam(name = "Locale", targetNamespace = "")
String locale,
@WebParam(name = "Result", targetNamespace = "", mode = WebParam.Mode.OUT)
Holder<Result> result,
@WebParam(name = "ClientLevel", targetNamespace = "", mode = WebParam.Mode.OUT)
Holder<UgClientLevel> clientLevel);
Вот сгенерированный объект, которому xml сопоставляется:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "UgClientLevel", propOrder = {
"name",
"buySumma",
"curLevelSumma",
"curLevelCode",
"curLevelName",
"nextLevelSumma",
"nextLevelCode",
"nextLevelName",
"toNextLevelSumma",
"availableBonusAmount",
"curMarketingLevelName"
})
public class UgClientLevel {
@XmlElementRef(name = "Name", type = JAXBElement.class, required = false)
protected JAXBElement<String> name;
@XmlElement(name = "BuySumma")
protected BigDecimal buySumma;
@XmlElement(name = "CurLevelSumma")
protected BigDecimal curLevelSumma;
@XmlElement(name = "CurLevelCode")
protected Integer curLevelCode;
@XmlElement(name = "CurLevelName")
protected String curLevelName;
@XmlElement(name = "NextLevelSumma")
protected BigDecimal nextLevelSumma;
@XmlElement(name = "NextLevelCode")
protected Integer nextLevelCode;
@XmlElement(name = "NextLevelName")
protected String nextLevelName;
@XmlElement(name = "ToNextLevelSumma")
protected BigDecimal toNextLevelSumma;
@XmlElement(name = "AvailableBonusAmount")
protected Long availableBonusAmount;
@XmlElement(name = "CurMarketingLevelName")
protected String curMarketingLevelName;
}
Создание wsdl и объектов завершено используя плагин и откройте api:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
</execution>
</executions>
<configuration>
<wsdlUrls>
<wsdlUrl>http://aa-test.web.local/C-UG/D?wsdl</wsdlUrl>
</wsdlUrls>
<packageName>ru.uu.esm.mm.ddd.soap</packageName>
<sourceDestDir>${project.build.sourceDirectory}</sourceDestDir>
</configuration>
</plugin>
В чем проблема?
Все работает хорошо, пока не появится новое поле в xml, которое дает сервер B, которого у нас нет все еще сгенерировано в нашей сущности.
Примером является сущность UgClientLevel, при формировании этого объекта в xml есть поле SavedBonusMoney, которого нет в UgClientLevel.
В такой ситуации мы получаю ошибку:
javax.xml.ws.soap.SOAPFaultException: Unmarshalling Error: unexpected element (uri:"", local:"SavedBonusMoney"). Expected elements are <{}BuySumma>,<{}CurLevelName>,<{}NextLevelCode>,<{}AvailableBonusAmount>,<{}NextLevelSumma>,<{}ToNextLevelSumma>,<{}CurMarketingLevelName>,<{}NextLevelName>,<{}CurLevelCode>,<{}CurLevelSumma>,<{}Name>
at org.apache.cxf.jaxws.JaxWsClientProxy.mapException(JaxWsClientProxy.java:195)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:145)
at com.sun.proxy.$Proxy237.getClientLevel(Unknown Source)
Оказывается, изменения не обратно совместимы.
Что хочу?
Хочу сделать так, чтобы при новой поле добавляется к xml службой B, при запросе от службы A это поле игнорируется, если оно не сгенерировано в объекте, к которому выполняется сопоставление xml.
Как я могу добиться желаемое поведение?