У меня есть фиксированная структура XML, которая уже используется другими приложениями. Некоторые из них являются сторонними, поэтому изменение XML не является вариантом.@XmlJavaTypeAdapter не вызывает TypeAdapter
В XML содержится раздел, который я пытаюсь развязать. Ниже приведена сокращенная версия. Этот элемент является дочерним элементом других элементов.
<premium>
<allowInstalments>true</allowInstalments>
<annualPremium>2964.23</annualPremium>
<!-- other various elements -->
<calcElement partname="driver">
<driverXs>300.00</driverXs>
<seq>1</seq>
</calcElement>
<calcElement partname="ratingData">
<baseMiles>6000</baseMiles>
<vehicleGroup>15</vehicleGroup>
<documentVersion>4</documentVersion>
</calcElement>
</premium>
Чтобы проверить, что это демаршализует правильно (и маршалом, но я пытаюсь распаковать в данный момент), я написал следующий тест:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {RegressionApplication.class})
public class AdaptedCalcElementTest {
@Autowired
@Qualifier(value = "unmarshaller")
private Unmarshaller unmarshaller;
@Test
public void canUnmarshallIntoDriverCalcElement() throws Exception {
String xml = "<wrapper><calcElement partname=\"driver\">" +
"<driverXs>300.00</driverXs>" +
"<seq>1</seq>" +
"</calcElement></wrapper>";
CalcElementWrapper calcElementWrapper = (CalcElementWrapper) unmarshaller.unmarshal(Input.from(xml).build());
assertThat(calcElementWrapper, notNullValue());
assertThat(calcElementWrapper.listElements, notNullValue());
assertThat(calcElementWrapper.listElements, hasSize(1));
CalcElement calcElement = calcElementWrapper.listElements.get(0);
assertThat(calcElement, instanceOf(DriverCalcElement.class));
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "wrapper")
public static class CalcElementWrapper {
@XmlJavaTypeAdapter(CalcElementAdapter.class)
public List<CalcElement> listElements;
}
}
Мой класс адаптер создает правильный CalcElement расширенный класс на основе атрибута имени пути:
public class CalcElementAdapter extends XmlAdapter<CalcElementAdapter.AdaptedCalcElement, CalcElement> {
@Override
public CalcElement unmarshal(CalcElementAdapter.AdaptedCalcElement v) throws Exception {
if (v.partname.equalsIgnoreCase("driver")) {
DriverCalcElement calcElement = new DriverCalcElement();
calcElement.setPartname(v.partname);
calcElement.setDriverXs(new BigDecimal(v.driverXs));
calcElement.setSeq(new Integer(v.seq));
return calcElement;
} else if (v.partname.equalsIgnoreCase("ratingData")) {
RatingDataCalcElement calcElement = new RatingDataCalcElement();
calcElement.setBaseMiles(new Integer(v.baseMiles));
calcElement.setDocumentVersion(new Integer(v.documentVersion));
calcElement.setVehicleGroup(new Integer(v.vehicleGroup));
return calcElement;
}
return null;
}
@Override
public CalcElementAdapter.AdaptedCalcElement marshal(CalcElement v) throws Exception {
return null;
}
public static class AdaptedCalcElement {
@XmlAttribute
public String partname;
public String driverXs;
public String seq;
public String baseMiles;
public String vehicleGroup;
public String documentVersion;
}
}
и в CalcElement и производные классы определяются следующим образом:
public abstract class CalcElement {
private String partname;
@XmlAttribute
public String getPartname() {
return partname;
}
public void setPartname(String partname) {
this.partname = partname;
}
}
public class DriverCalcElement extends CalcElement {
private BigDecimal driverXs;
private Integer seq;
public BigDecimal getDriverXs() {
return driverXs;
}
public void setDriverXs(BigDecimal driverXs) {
this.driverXs = driverXs;
}
public Integer getSeq() {
return seq;
}
public void setSeq(Integer seq) {
this.seq = seq;
}
}
public class RatingDataCalcElement extends CalcElement {
private Integer baseMiles;
private Integer vehicleGroup;
private Integer documentVersion;
public Integer getBaseMiles() {
return baseMiles;
}
public void setBaseMiles(Integer baseMiles) {
this.baseMiles = baseMiles;
}
public Integer getVehicleGroup() {
return vehicleGroup;
}
public void setVehicleGroup(Integer vehicleGroup) {
this.vehicleGroup = vehicleGroup;
}
public Integer getDocumentVersion() {
return documentVersion;
}
public void setDocumentVersion(Integer documentVersion) {
this.documentVersion = documentVersion;
}
}
unmarshaller сконфигурирован как:
@Bean(name = "unmarshaller")
Unmarshaller getUnmarshaller() {
return getJaxb2Marshaller();
}
private Jaxb2Marshaller getJaxb2Marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("com.itb.lego.regression");
return marshaller;
}
Я пытался следовать блог вывешивать @ Блез-doughan, но я не могу видеть то, что мне не хватает.
Однако тест не работает, поскольку он не вызывает адаптер для элементов calcElement. Что мне не хватает?