繁体   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