亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

基于屬性值的杰克遜 XML 綁定元素

基于屬性值的杰克遜 XML 綁定元素

狐的傳說 2022-09-22 16:37:13
我有以下結構:XML<participants>    <participant side="AWAY">        <team id="18591" name="Orlando Apollos" />    </participant>    <participant side="HOME">        <team id="18594" name="Memphis Express" />    </participant></participants>如果我使用帶有注釋的庫,如何將參與者字段綁定到兩個不同的對象,并使用 和 的屬性綁定字段。FasterXML JacksonJAXBParticipantparticipantHomeparticipantAwaysideAWAYHOME使用以下對象顯然不起作用,因為存在重復的字段:import javax.xml.bind.annotation.XmlElement;import javax.xml.bind.annotation.XmlRootElement;@XmlRootElement(name = "participants")public class Participants {    @XmlElement(name = "participant")    Participant participantHome;    @XmlElement(name = "participant")    Participant participantAway;}如何使用注釋或自定義實現動態綁定這些元素?JAXBJAXB
查看完整描述

3 回答

?
慕哥9229398

TA貢獻1877條經驗 獲得超6個贊

您需要編寫自定義的去細節,因為沒有注釋允許將列表項綁定到 object 中的給定屬性。如果已在使用,請嘗試實現自定義 Json 序列化程序,而不是自定義 Xml適配器。我們可以通過將內部對象反序列化為 來簡化我們的自定義去序列化器。簡單示例:JacksonParticipantMap

import com.fasterxml.jackson.core.JsonParser;

import com.fasterxml.jackson.core.JsonToken;

import com.fasterxml.jackson.databind.DeserializationContext;

import com.fasterxml.jackson.databind.JsonDeserializer;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

import com.fasterxml.jackson.databind.type.MapType;

import com.fasterxml.jackson.dataformat.xml.XmlMapper;


import java.io.File;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

import java.util.Map;


public class XmlMapperApp {


    public static void main(String[] args) throws Exception {

        File xmlFile = new File("./resource/test.xml").getAbsoluteFile();


        XmlMapper xmlMapper = new XmlMapper();


        Participants result = xmlMapper.readValue(xmlFile, Participants.class);

        System.out.println(result);

    }

}


class ParticipantsXmlAdapter extends JsonDeserializer<Participants> {


    @Override

    public Participants deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {

        List<Map<String, Object>> participants = readParticipantsMap(p, ctxt);


        Participants result = new Participants();

        for (Map<String, Object> participantMap : participants) {

            Object side = participantMap.get("side").toString();

            if ("AWAY".equals(side)) {

                result.setParticipantAway(convert((Map<String, Object>) participantMap.get("team")));

            } else if ("HOME".equals(side)) {

                result.setParticipantHome(convert((Map<String, Object>) participantMap.get("team")));

            }

        }


        return result;

    }


    private List<Map<String, Object>> readParticipantsMap(JsonParser p, DeserializationContext ctxt) throws IOException {

        MapType mapType = ctxt.getTypeFactory().constructMapType(Map.class, String.class, Object.class);

        JsonDeserializer<Object> mapDeserializer = ctxt.findRootValueDeserializer(mapType);

        List<Map<String, Object>> participants = new ArrayList<>();

        p.nextToken(); // skip Start of Participants object

        while (p.currentToken() == JsonToken.FIELD_NAME) {

            p.nextToken(); // skip start of Participant

            Object participant = mapDeserializer.deserialize(p, ctxt);

            participants.add((Map<String, Object>) participant);

            p.nextToken(); // skip end of Participant

        }


        return participants;

    }


    private Participant convert(Map<String, Object> map) {

        Participant participant = new Participant();

        participant.setId(Integer.parseInt(map.get("id").toString()));

        participant.setName(map.get("name").toString());


        return participant;

    }

}


@JsonDeserialize(using = ParticipantsXmlAdapter.class)

class Participants {


    private Participant participantHome;

    private Participant participantAway;


    // getters, setters, toString

}


class Participant {

    private int id;

    private String name;


    // getters, setters, toString

}

指紋:


Participants{participantHome=Participant{id=18594, name='Memphis Express'}, participantAway=Participant{id=18591, name='Orlando Apollos'}}



查看完整回答
反對 回復 2022-09-22
?
守著一只汪

TA貢獻1872條經驗 獲得超4個贊

您可以使用“參與者列表”代替兩個不同的參與者。用@XmlAttribute注釋(名稱 = “side”,必需 = true)。然后創建兩個不同的參與者對象并將其添加到列表中。


查看完整回答
反對 回復 2022-09-22
?
月關寶盒

TA貢獻1772條經驗 獲得超5個贊

這里有一些很棒的答案和替代方案,但我決定使用與列表綁定的混合,并通過實現返回正確的主隊或客隊的 getter 方法來返回正確的或團隊,以基本上扁平化 .這將減少在整個應用程序中處理列表時的計算量。homeawayList


我將以下代碼添加到我的父類(每個/參與者):homeaway


Participant getHome() {

    return (Participant) participants.stream()

            .filter(p -> p.getSide().equalsIgnoreCase("home"));

}


Participant getAway() {

    return (Participant) participants.stream()

            .filter(p -> p.getSide().equalsIgnoreCase("away"));

}

感謝您的幫助!


查看完整回答
反對 回復 2022-09-22
  • 3 回答
  • 0 關注
  • 106 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號