Use JAXB XMLAnyElement type of style to return dynamic element names

前端 未结 2 1553
悲&欢浪女
悲&欢浪女 2020-12-18 14:02

I have read a lot of answers in these forums, as well as other blog posts, but I can\'t quite seem to connect the pieces together.

So, we start with a basic POJO con

2条回答
  •  甜味超标
    2020-12-18 14:33

    Depends on the solution listed above, I've came into this MapAdapter that addresses both marshaling and unmarshalling process.

    @XmlType
    public class MapWrapper{
        private List> properties = new ArrayList<>();
    
        public MapWrapper(){
    
        }
        @XmlAnyElement
        public List> getProperties() {
            return properties;
        }
        public void setProperties(List> properties) {
            this.properties = properties;
        }
        @Override
        public String toString() {
            return "MapWrapper [properties=" + toMap() + "]";
        }
    
    
        public Map toMap(){
            //Note: Due to type erasure, you cannot use properties.stream() directly when unmashalling is used.
            List props = properties;
            return props.stream().collect(Collectors.toMap(MapWrapper::extractLocalName, MapWrapper::extractTextContent));
        }
    
        @SuppressWarnings("unchecked")
        private static String extractLocalName(Object obj){
    
            Map, Function> strFuncs = new HashMap<>();
            strFuncs.put(JAXBElement.class, (jaxb) -> ((JAXBElement)jaxb).getName().getLocalPart());
            strFuncs.put(Element.class, ele -> ((Element) ele).getLocalName());
            return extractPart(obj, strFuncs).orElse("");
        }
    
    
        @SuppressWarnings("unchecked")
        private static String extractTextContent(Object obj){
            Map, Function> strFuncs = new HashMap<>();
            strFuncs.put(JAXBElement.class, (jaxb) -> ((JAXBElement)jaxb).getValue());
            strFuncs.put(Element.class, ele -> ((Element) ele).getTextContent());
            return extractPart(obj, strFuncs).orElse("");
        }
    
        private static  Optional extractPart(ObjType obj, Map, Function> strFuncs){
            for(Class clazz : strFuncs.keySet()){
                if(clazz.isInstance(obj)){
                    return Optional.of(strFuncs.get(clazz).apply(obj));
                }
            }
            return Optional.empty();
        }
    }
    
    public class MapAdapter extends XmlAdapter>{
    
        @Override
        public Map unmarshal(MapWrapper v) throws Exception {
            return v.toMap();
        }
    
        @Override
        public MapWrapper marshal(Map m) throws Exception {
            MapWrapper wrapper = new MapWrapper();
    
            for(Map.Entry entry : m.entrySet()){
                 wrapper.addEntry(new JAXBElement(new QName(entry.getKey()), String.class, entry.getValue()));
            }
    
            return wrapper;
        }
    
    }
    

    I've post the full the full post here (in another post), where comments as well as examples are also provided..

提交回复
热议问题