簡體   English   中英

JAXB XmlAdapter如何用於編組列表?

[英]How can JAXB XmlAdapter be used to marshall lists?

此類的實例是大型對象圖的一部分,而不是對象圖的根:

public class Day
{
    public Day(LocalDate date, List<LocalTime> times)
    {
        this.date = date;
        this.times = times;
    }

    public Day()
    {
        this(null, null);
    }

    public LocalDate getDate()
    {
        return date;
    }

    public List<LocalTime> getTimes()
    {
        return times;
    }

    private final LocalDate date;

    private final List<LocalTime> times;
}

使用Jersey和JAXB將對象圖轉換為JSON。 XmlAdapter的注冊為LocalDateLocalTime

問題在於它僅適用於date屬性,而不適用於times屬性。 我懷疑這與times是一個列表而不是一個單一值有關。 然后,如何告訴Jersey / JAXB使用注冊的XmlAdaptertimes列表中的每個元素編組?

更新:

我通過添加標量LocalTime屬性並觀察JSON中的預期輸出,確認LocalTime編組確實適用於標量LocalTime屬性。

為了完整起見,這里是package-info.java:

@XmlJavaTypeAdapters({
    @XmlJavaTypeAdapter(value = LocalDateAdapter.class, type = LocalDate.class),
    @XmlJavaTypeAdapter(value = LocalTimeAdapter.class, type = LocalTime.class)
})
package same.package.as.everything.else;

LocalDateAdapter

public class LocalDateAdapter extends XmlAdapter<String, LocalDate>
{
    @Override
    public LocalDate unmarshal(String v) throws Exception
    {
        return formatter.parseLocalDate(v);
    }

    @Override
    public String marshal(LocalDate v) throws Exception
    {
        return formatter.print(v);
    }

    private final DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyyMMdd");
}

LocalTimeAdapter

public class LocalTimeAdapter extends XmlAdapter<String, LocalTime>
{
    @Override
    public LocalTime unmarshal(String v) throws Exception
    {
        return formatter.parseLocalTime(v);
    }

    @Override
    public String marshal(LocalTime v) throws Exception
    {
        return formatter.print(v);
    }

    private final DateTimeFormatter formatter = DateTimeFormat.forPattern("HHmm");

類的XmlAdapter應用於該類型的映射字段/屬性,對於集合,則應用於集合中的每個項目。 下面的示例證明了這可行。 您是否嘗試過將示例獨立運行到XML以驗證這種方式的映射。 懷疑問題是XmlAdapter以外的其他問題。

StringAdapter

以下XmlAdapter將在解組操作時將String轉換為小寫,並在編組時將其轉換為大寫。

package forum14569293;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class StringAdapter extends XmlAdapter<String, String> {

    @Override
    public String unmarshal(String v) throws Exception {
        return v.toLowerCase();
    }

    @Override
    public String marshal(String v) throws Exception {
        return v.toUpperCase();
    }

}

包信息

就像您的問題一樣,將使用包級別@XmlJavaTypeAdapters批注來注冊XmlAdapter 這將為此包內所有映射的String屬性注冊此XmlAdapter (請參閱: http : XmlAdapter )。

@XmlJavaTypeAdapters({
    @XmlJavaTypeAdapter(value=StringAdapter.class, type=String.class)
})
package forum14569293;

import javax.xml.bind.annotation.adapters.*;

下面是一個與您的Day類相似的示例域模型,具有兩個映射的屬性。 第一個是String類型,第二個是List<String> 關於Day類,我注意到的一件事是您只有get方法。 這意味着您將需要為JAXB impl添加一個@XmlElement批注,以考慮該映射屬性。

package forum14569293;

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlRootElement
public class Root {

    public Root(String foo, List<String> bar) {
        this.foo = foo;
        this.bar = bar;
    }

    public Root() {
        this(null, null);
    }

    @XmlElement
    public String getFoo() {
        return foo;
    }

    @XmlElement
    public List<String> getBar() {
        return bar;
    }

    private final String foo;
    private final List<String> bar;

}

演示

package forum14569293;

import java.util.*;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        List<String> bar = new ArrayList<String>(3);
        bar.add("a");
        bar.add("b");
        bar.add("c");
        Root root = new Root("Hello World", bar);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);

    }

}

產量

下面是運行演示代碼的輸出,我們看到XmlAdapter將所有字符串都轉換為大寫。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <bar>A</bar>
    <bar>B</bar>
    <bar>C</bar>
    <foo>HELLO WORLD</foo>
</root>

UPDATE

謝謝。 我嘗試了一下,XML只包含一個空標記,這意味着JAXB不喜歡POJO模型。 (也許它應該可序列化?)

JAXB不需要POJO實現Serializable

這很有趣,因為它似乎表明JAXB唯一起作用的部分是將其批注和其他一些接口(例如XmlAdapter)借給JSON(反)序列化器,並且關系就在那里結束了。

這取決於用作JSON綁定層的內容。 JAXB(JSR-222)規范不涵蓋JSON綁定,因此這種類型的支持超出了規范。 EclipseLink JAXB(MOXy)提供了本機JSON綁定(我是MOXy主管),您可以執行以下操作:

Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, false);
marshaller.marshal(root, System.out);

並獲得將XmlAdapter考慮在內的以下輸出:

{
   "bar" : [ "A", "B", "C" ],
   "foo" : "HELLO WORLD"
}

但是,當我有機會的時候,我將盡我所能來使JAXB生成XML,這可能會揭示出其他東西。

這將很有用,因為我不認為您看到的是JAXB問題,而是您正在使用的JSON綁定層中的問題。

如何編組 ArrayList<object> [] 在 JAXB 中?<div id="text_translate"><p> 我有一個 ArrayList[] 類型的變量(列表),我想將它保存在 XML 中。 我嘗試了 JAXB,但它只保存了“”字符串(“的重復”等於 list.length)並且在 ArrayLists 中沒有任何項目。如果我嘗試二維數組,它工作正常。如果我嘗試 ArrayList,它也可以正常工作。我怎么解決這個問題?</p><p> 我的代碼類似於:</p><pre> @XmlRootElement public class SomeClass { @XmlElement(name="part") private final ArrayList&lt;Object&gt;[] list; ... constructor, which fills the list variable }</pre><p> 有人可以告訴我該怎么做嗎? 請。<br><br></p></div></object>

[英]How to marshall ArrayList<Object>[] in JAXB?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM