Невозможно Unmarshall XML в Java с использованием JAXB без каких-либо аннотаций - Нет ошибки, но Unmarshalling является неправильным
Я пытаюсь преобразовать содержимое XML в объект Java с использованием JAXB без каких-либо аннотаций. Моя структура XML-файла (CustomerDtl.xml) упоминается ниже
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<basePojo>
<customerId>C001</customerId>
<customerList>
<Customer>
<name>Ram</name>
<phoneNo>123445</phoneNo>
</Customer>
<Customer>
<name>Tom</name>
<phoneNo>2332322</phoneNo>
</Customer>
</customerList>
</basePojo>
и мои pojos
BasePojo.java
package pojo;
import java.util.List;
import pojo.Customer;
public class BasePojo {
List<Customer> customerList;
String customerId;
public List<Customer> getCustomerList() {
return customerList;
}
public void setCustomerList(List<Customer> customerList) {
this.customerList = customerList;
}
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
}
Customer.java
package pojo;
public class Customer {
private String name;
private String phoneNo;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoneNo() {
return phoneNo;
}
public void setPhoneNo(String phoneNo) {
this.phoneNo = phoneNo;
}
}
Ниже упомянутый фрагмент кода, который я написал для преобразования содержимого XML в объект Java
try {
JAXBContext jc = JAXBContext.newInstance(BasePojo.class);
StreamSource xml = new StreamSource("CustomerDtl.xml");
Unmarshaller unmarshaller = jc.createUnmarshaller();
JAXBElement<BasePojo> jaxbElementObject = unmarshaller.unmarshal(
xml, BasePojo.class);
BasePojo bPojo = jaxbElementObject.getValue();
System.out.println("id="+bPojo.getCustomerId());
System.out.println("list size="+bPojo.getCustomerList().size());
Iterator iterator = bPojo.getCustomerList().iterator();
while (iterator.hasNext()) {
Customer studentDetails = (Customer) iterator.next();
System.out.println("Print Name:" + studentDetails.getName());
}
} catch (JAXBException e) {
System.out.println("Exception:" + e);
}
И выход этого кода
id=C001
list size=1
list size=[pojo.Customer@3e3abc88]
Print Customer Name:null
После выполнения этой программы она печатает правильный customerId, но печатает неправильный размер списка клиентов 1. Хотя размер списка равен 1, и список содержит объект Customer, но когда я перебираю список и пытаюсь получить другое значение свойства Customer, я получаю нулевое значение.
Может ли кто-нибудь объяснить мне, что мне нужно исправить? С помощью аннотации я попытался, и она работает, как ожидалось. Разве это не возможно без аннотации?
3 ответа
В XML не нужно указывать имя класса (Customer
) как ребенок вашего списка (customerList
), просто используйте имя списка непосредственно для каждого элемента.
Итак, измените xml следующим образом:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<basePojo>
<customerId>C001</customerId>
<customerList>
<name>Ram</name>
<phoneNo>123445</phoneNo>
</customerList>
<customerList>
<name>Tom</name>
<phoneNo>2332322</phoneNo>
</customerList>
</basePojo>
Попробуйте что-то вроде ниже
try {
XMLInputFactory xif = XMLInputFactory.newFactory();
StreamSource xml = new StreamSource("CustomerDtl.xml");
XMLStreamReader xsr = xif.createXMLStreamReader(xml);
while(xsr.hasNext()) {
if(xsr.isStartElement() && "Customer".equals(xsr.getLocalName())) {
break;
}
xsr.next();
}
JAXBContext jc = JAXBContext.newInstance(Customer.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Customer customer = unmarshaller.unmarshal(xsr, Customer.class).getValue();
System.out.println(customer.getName());
} catch (JAXBException e) {
System.out.println("Exception:" + e);
}
Здесь вы идете, если вы не хотите никаких аннотаций (с точным XML, который вы поделились).
1) Оберните ваш список в класс обертки (для обработки customerList)
2) Теперь, как я спросил в комментарии, если у вас есть элемент "Клиент", то по умолчанию распознанное имя "xml" будет с маленькой буквой c. Если вы не хотите комментировать даже это, то обрабатывайте это, читая.
После того, как вы сказали это, вот рабочий пример (с работоспособным main), модифицирующий ваш BasePojo
package pojo;
import java.io.ByteArrayInputStream;
import java.io.StringReader;
import java.util.Iterator;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.StreamReaderDelegate;
import javax.xml.transform.stream.StreamSource;
public class BasePojo {
String customerId;
CustomerList customerList;
public CustomerList getCustomerList() {
return customerList;
}
public void setCustomerList(CustomerList customerListObject) {
this.customerList = customerListObject;
}
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
public static void main(String[] args) {
try {
String customerData = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
+ "<basePojo>\n"
+ "<customerId>C001</customerId>\n"
+ "<customerList>\n"
+ " <Customer>\n"
+ " <name>Ram</name>\n"
+ " <phoneNo>123445</phoneNo>\n"
+ " </Customer>\n"
+ "\n"
+ " <Customer>\n"
+ " <name>Tom</name>\n"
+ " <phoneNo>2332322</phoneNo>\n"
+ " </Customer>\n"
+ "</customerList>\n"
+ "</basePojo>";
JAXBContext jc = JAXBContext.newInstance(BasePojo.class);
StringReader reader = new StringReader(customerData);
StreamSource xml = new StreamSource(reader);
XMLInputFactory xif = XMLInputFactory.newFactory();
XMLStreamReader xsr = xif.createXMLStreamReader(new ByteArrayInputStream(customerData.getBytes("UTF-8")));
xsr = new StreamReaderDelegate(xsr) {
@Override
public String getLocalName() {
String localName = super.getLocalName();
if ("Customer".equals(localName)) {
return "customer";
}
return localName;
}
};
Unmarshaller unmarshaller = jc.createUnmarshaller();
JAXBElement<BasePojo> jaxbElementObject = unmarshaller.unmarshal(xsr, BasePojo.class);
BasePojo bPojo = jaxbElementObject.getValue();
System.out.println("id=" + bPojo.getCustomerId());
System.out.println("list size=" + bPojo.getCustomerList().getCustomer().size());
Iterator iterator = bPojo.getCustomerList().getCustomer().iterator();
while (iterator.hasNext()) {
Customer studentDetails = (Customer) iterator.next();
System.out.println("Print Name:" + studentDetails.getName());
}
} catch (Exception e) {
System.out.println("Exception:" + e);
}
}
}
class CustomerList {
private List<Customer> customer;
public List<Customer> getCustomer() {
return customer;
}
public void setCustomer(List<Customer> customer) {
this.customer = customer;
}
}