有没有办法将 Class 作为参数传递给 JAXB XMLAdapter 或从另一个类访问 Getter 方法

问题描述

我正在尝试为我的一个对象创建一个 XMLAdapter 类。我需要从另一个类访问 Getters,以便可以从该类的 Getters` 填充某些对象,但我无法这样做。

基本上,我想在 Child 中访问我的 GetterXMLAdapter 方法。我可以创建 Child 类的对象并访问,但结果是 NULL。最初,我在 ObjectsChild 类中填充 Parent。我想在 XML Adapter 中访问相同的值,所以我想知道是否有办法将类的引用传递给我的 XMLAdapter

我有以下 Parent 类,其中包含值:

@XmlAccessorType(XmlAccesstype.FIELD)
@XmlTransient
@XmlSeeAlso({Child.class})
public class Parent{
    private String eventID;
}

以下是我的 Child 类,它将在编组期间用于创建 XML

@XmlRootElement(name = "child")
@XmlType(name = "child",propOrder = { "name","extension"})
public class Child extends Parent
{
    
    @XmlElement (name = "name") 
    private String name;
    
    @JsonIgnore
    @XmlJavaTypeAdapter (ExtensionAdapter.class)
    @XmlElement (name = "extension") 
    private Extension extension;

}

以下是我的扩展类:

@NoArgsConstructor
@AllArgsConstructor
@XmlAccessorType(XmlAccesstype.FIELD)
public class Extension {
    private String eventID;
}

以下是我的 XMLAdapter 课:

public class ExtensionAdapter extends XmlAdapter<Child,Extension> {

    @Override
    public Extension unmarshal(Child valueType) throws Exception {
        System.out.println("UN-MARSHALLING");
        return null;
    }

    @Override
    public Child marshal(Extension boundType) throws Exception {
        System.out.println("MARSHALLING");
        System.out.println(boundType);
        //If I create the New child type then I am unable to access the eventID from its getter as Child class is nulll
        Child be = new Child();
        be.setEventID(boundType.getEventID());
        return be;
    }
}

基本上,我想访问 Child 中的 Getter glass XMLAdapter 方法,以便我可以用它填充我的 ExtensionEventID。我尝试了很多东西,但没有任何效果,所以我在这里发帖。

有没有办法将我的 Child 类作为参数传递给 XMLAdapter,以便我可以从中访问 Getter 方法?因为如果我创建一个 Child 类的新对象,那么它的所有 Getter 方法都是空的。但是,一开始我会填充 ParentChild 类(名称和 eventID)中的所有字段。我只想使用 ExtensioneventIDXMLAdapter 中填充相同的值。

我希望我能够解释这种需要。如果您有任何建议或示例代码,那将非常有用。

请注意:我在这里使用了非常示例代码。我知道我想要实现的任何目标都可以使用适当的 POJO 和 JAXB 注释来实现,但我的实际类很复杂,我不允许修改它。我只能添加新的注释。因此,我正在尝试使用 XMLAdapter 来实现这一点。

解决方法

我想实现这样的目标,所以我无需访问类就可以做到这一点。发布答案,以便将来对某人有用。

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.lang3.NotImplementedException;

import io.openepcis.model.jaxb.MyAdapter.MapWrapper;

public class MyAdapter extends XmlAdapter<MapWrapper,Map<String,Object>> {

    private DocumentBuilder documentBuilder;

    public MyAdapter() throws Exception {
        documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    }

    @Override
    public Map<String,Object> unmarshal(MapWrapper valurType) throws Exception {
        throw new NotImplementedException();
    }

    @SuppressWarnings("unchecked")
    @Override
    public MapWrapper marshal(Map<String,Object> m) throws Exception {
        if (m == null) {
            return null;
        }
        MapWrapper wrapper = new MapWrapper();
        List elements = new ArrayList();
        for (Map.Entry<String,Object> property : m.entrySet()) {
            if (property.getValue() instanceof Map) {
                elements.add(new JAXBElement<MapWrapper>(new QName(getCleanLabel(property.getKey())),MapWrapper.class,marshal((Map) property
                                    .getValue())));

            } else {
                elements.add(new JAXBElement<String>(new QName(getCleanLabel(property.getKey())),String.class,property.getValue().toString()));
            }

        }
        wrapper.elements = elements;
        return wrapper;

    }

    // Return a XML-safe attribute. Might want to add camel case support
    private String getCleanLabel(String attributeLabel) {
        attributeLabel = attributeLabel.replaceAll("[()]","").replaceAll("[^\\w\\s]","_").replaceAll(" ","_");
        return attributeLabel;
    }

    public static class MapWrapper {
        @XmlAnyElement
        List elements;
    }