атрибуты маршала внутри элементов XML с помощью JAXB - PullRequest
0 голосов
/ 11 сентября 2018

Я работаю с Spring JPA и имею следующую сущность:

@Entity
@Table(name = Constants.ENTITY_TABLE_PREFIX + "ENTRY")
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "monObj_info")
public class EntryXML implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @XmlAttribute
    private long id;

    @Column(name = "ip_address", nullable = true)
    @XmlElement
    private String ip_address;

    @Column(name = "network_element_name", nullable = false)
    @XmlElement
    private String network_element_name;

    public EntryXML() {}

    public EntryXML(long id, String ip_address, String   network_element_name) {
        super();
        this.id = id;
        this.ip_address = ip_address;
        this.network_element_name = network_element_name;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getIp_address() {
        return ip_address;
    }

    public void setIp_address(String ip_address) {
        this.ip_address = ip_address;
    }

    public String getNetwork_element_name() {
        return network_element_name;
    }

    public void setNetwork_element_name(String network_element_name) {
        this.network_element_name = network_element_name;
    }

}

и конечную точку:

@RestController
public class EntryXMLEndpoint {

    @Autowired
    private IEntryXMLService service;

    @RequestMapping(value = "/restxml", produces = { "application/xml" })
    public EntryXML findEntries() {
        EntryXML record = service.findById(1);
        return record;
    }

}

Теперь запрошенный ответ:

<monObj_info id="1">
 <atribute name="ip_address" value="xx.xxx.xxx.x"/>
 <atribute name="network_element_name" value="xxxxxx"/>
</monObj_info>

Конечно, я получаю:

<monObj_info id="1">
  <ip_address>xx.xxx.xxx.x</ip_address>
  <network_element_name>xxxxxx</network_element_name>
</monObj_info>

Я читаю похожие посты, но проблема в том, что я не могу создать список с необходимыми элементами внутри моего класса сущностей, так как он не сопоставляется ни с одним столбцом всоответствующая таблица, какие-либо предложения?

1 Ответ

0 голосов
/ 11 сентября 2018

Вы можете достичь своей цели прямым, но несколько хакерским способом.

Поскольку вам не нужны свойства ip_address и network_element_name Чтобы быть маршалированным и демаршированным напрямую, вам необходимо удалить их @XmlElement аннотацию и добавьте @XmlTransient.

Вместо этого вы хотите, чтобы некоторые элементы <atribute name="..." value="..." /> маршалировали и разбирали Поэтому вам необходимо добавить следующие вещи в ваш EntryXML класс:

  • и attributes свойство, содержащее список атрибутов. Он помечен @XmlElement, так что он будет частью XML-маршалинга и демаршаллинга. Он помечен @Transient, так что не будет частью сохранения базы данных.
  • простой вспомогательный класс Attribute для хранения имени и значения. name и value помечены @XmlAttribute, так что они будут частью XML-маршалинга и демаршаллинга.
  • a Обратный вызов события Marshal ( beforeMarshal ) для выполнения преобразования из ip_address и network_element_name в список attributes.
  • и обратный вызов Unmarshal Event ( afterUnmarshal ) для выполнения обратного преобразования.

@XmlElement(name = "atribute")
@Transient  // from package javax.persistence
private List<Attribute> attributes;

// there is no need for getAttributes and setAttributes methods

private static class Attribute {

    @SuppressWarnings("unused")  // called by the unmarshaller
    Attribute() {
    }

    Attribute(String name, String value) {
        this.name = name;
        this.value = value;
    }

    @XmlAttribute
    private String name;

    @XmlAttribute
    private String value;
}

@SuppressWarnings("unused") // this method is called only by the marshaller
private boolean beforeMarshal(Marshaller marshaller) {
    attributes = new ArrayList<>();
    attributes.add(new Attribute("ip_address", ip_address));
    attributes.add(new Attribute("network_element_name", network_element_name));
    return true;
}

@SuppressWarnings("unused") // this method is called only by the unmarshaller
private void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
    if (attributes != null) {
        for (Attribute attribute : attributes) {
            switch (attribute.name) {
            case "ip_address":
                ip_address = attribute.value;
                break;
            case "network_element_name":
                network_element_name = attribute.value;
                break;
            }
        }
    }
}

Тогда вывод XML будет выглядеть так:

<monObj_info id="1">
    <atribute name="ip_address" value="xx.xxx.xxx.x"/>
    <atribute name="network_element_name" value="xxxxxx"/>
</monObj_info>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...