java - 使用 JAXB XMLAnyElement 类型的样式返回动态元素名称

标签 java jaxb resteasy

我在这些论坛以及其他博客文章中阅读了很多答案,但我似乎无法将这些部分联系在一起。

因此,我们从包含 Map 属性的基本 POJO 开始。已经确定如何包装它,但它会返回一些值。我要做的是命名(又名标签)并使其成为有效的 XML“属性”。所以我们会得到一些值(value)。

我找到了一个例子(如果我能再找到它会链接)如下:

@XmlAnyElement
public List<JAXBElement<String>> getXmlProperties() {
   List<JAXBElement<String>> elements = new ArrayList<JAXBElement<String>>();
   for (Map.Entry<String, String> property: properties.entrySet()) 
      elements.add(new JAXBElement<String>(new QName(property.getKey()), 
      String.class, property.getValue()));
      return elements;
}

这工作得很好,但我在我的 Bean/Pojo 类中有这个,它与 GWT 前端共享,因此不能包含对 JAXBElement 和 QName 的引用(需要源代码)。

那么,有没有办法使用 XmlAdapter 和 JAXBElement/QName/XmlAnyElement 梦之队来获得类似的结果?顺便说一句,如果考虑到这一点,我正在使用 RESTEasy。

这是带有@XmlAnyElement+JAXBElement 的论坛帖子:Dynamic tag names with JAXB

最佳答案

我离答案不远 - 经过更多的试验后,我找到了正确的组合。

为不可映射的返回类型创建一个包装类。包装应包含/返回 List<JAXBElement<String>@XmlAnyElement 注释包装返回类型.

public class MapWrapper {
   @XmlAnyElement
    public List<JAXBElement<String>> properties = new ArrayList<JAXBElement<String>>();
}

创建一个编码到 MapWrapper 的 XmlAdapter

public class MapAdapter extends XmlAdapter<MapWrapper, Map<String,String>> {
    @Override
    public MapWrapper marshal(Map<String,String> m) throws Exception {
    MapWrapper wrapper = new MapWrapper();
    List<JAXBElement<String>> elements = new ArrayList<JAXBElement<String>>();
       for (Map.Entry<String, String> property: m.entrySet()) {
          elements.add(new JAXBElement<String>(
                    new QName(getCleanLabel(property.getKey())), 
          String.class, property.getValue()));
       }
       wrapper.elements=elements;
    return wrapper;
}

@Override
public Map<String,String> unmarshal(MapWrapper v) throws Exception {
            // TODO
    throw new OperationNotSupportedException();
}

// Return a lower-camel XML-safe attribute
private String getCleanLabel(String attributeLabel) {
    attributeLabel = attributeLabel.replaceAll("[()]", "")
            .replaceAll("[^\\w\\s]", "_").replaceAll(" ", "_")
            .toUpperCase();
    attributeLabel = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL,
            attributeLabel);
    return attributeLabel;
}
}

使用 XmlAdapter 注释您的不可映射类型

@XmlRootElement
public class SomeBean {

    @XmlJavaTypeAdapter(MapAdapter.class)
    public LinkedHashMap<String, String> getProperties() {
        return properties;
    }
}

像这样的 map :

My Property 1    My Value 1 
My Property 2    My Value 2

结果应该是:

<someBean>
   <properties>
     <myProperty1>My Value 1</myProperty1>
     <myProperty2>My Value 1</myProperty2>
   </properties>
</someBean>

希望这对其他人有帮助!

关于java - 使用 JAXB XMLAnyElement 类型的样式返回动态元素名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21382202/

相关文章:

java - 查找或初始化解决 "hostname in certificate didn' t 匹配所需的 keystore ”

java - 关于在Android上创建GUIS "dynamically"的问题

java - JAXB 模式与类/包的关系

java - 使用 CSV2TableLayout 解析 CSV 但出现问号

java - 如何让JRE访问自己?

java - Spring 休息 WS : How to handle multiple XML payloads in single endpoint?

java - Java中如何判断子类的类类型

java - RestEasy 可以扩展 @Path 吗?

jax-rs - 将请求范围的上下文字段注入(inject)到 RESTEasy 单例中

java - 让 GAE Shiro 和 Resteasy 协同工作