JAXB Configuration was broken by upgrading from JDK 1.7 to JDK 1.8 u05 for collections

五迷三道 提交于 2019-11-28 12:45:00

Background

When a collection property is mapped in JAXB it first checks the getter to see if the collection property has been pre-initialized. In the example below I want to have my property exposed as List<String>, but have the backing implementation be a LinkedList ready to hold 1000 items.

private List<String> foos = new LinkedList<String>(1000);

@XmlElement(name="foo")
public List<String> getFoos() {
    return foos;
}

Why Your Code Used to Work

If you previously had JAXB call the setter on a property mapped to a collection that returned a non-null response from the getter, then there was a bug in that JAXB implementation. Your code should not have worked in the previous version either.

How to Get the Setter Called

To have the setter called you just need to have your getter return null, on a new instance of the object. Your code could look something like:

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

@XmlRootElement(name = "Foo")
public class Foo {

    private List<CustomObject> list = null;

    @XmlElementWrapper(name = "Wrap")
    @XmlElement(name = "Item", required = true)
    public synchronized void setList(List<CustomObject> values) {
        if (null == list) {
            list = new ArrayList<CustomObject>();
        } else {
            list.clear();
        }
        list.addAll(values);
    }

    public synchronized List<CustomObject> getList() {
        if (null == list) {
            return null;
        }
        return new ArrayList(list);
    }

}

UPDATE

If you don't need to perform any logic on the List returned from JAXB's unmarshalling then using field access may be an acceptable solution.

@XmlRootElement(name = "Foo")
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {

    @XmlElementWrapper(name = "Wrap")
    @XmlElement(name = "Item", required = true)
    private List<CustomObject> list = null;

    public synchronized void setList(List<CustomObject> values) {
        if(null == list) {
            list = new ArrayList<CustomObject>();
        } else {
            list.clear();
        }
        list.addAll(values);
    }

    public synchronized List<CustomObject> getList() {
        return new ArrayList(list);
    }

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!