Java 使用样式的JAXB XMLAnyElement类型返回动态元素名称
我在这些论坛上读到了很多答案,还有其他的博客文章,但我似乎无法将这些部分联系起来 因此,我们从包含映射属性的基本POJO开始。已经确定了如何包装它,但这会返回一些值。我要做的是获取then名称(又称标签),并使其成为有效的XML“属性”。所以我们会得到一些价值 我发现了一个示例(如果我能再次找到它,将链接),如下所示:Java 使用样式的JAXB XMLAnyElement类型返回动态元素名称,java,jaxb,resteasy,Java,Jaxb,Resteasy,我在这些论坛上读到了很多答案,还有其他的博客文章,但我似乎无法将这些部分联系起来 因此,我们从包含映射属性的基本POJO开始。已经确定了如何包装它,但这会返回一些值。我要做的是获取then名称(又称标签),并使其成为有效的XML“属性”。所以我们会得到一些价值 我发现了一个示例(如果我能再次找到它,将链接),如下所示: @XmlAnyElement public List<JAXBElement<String>> getXmlProperties() { List&
@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;
}
@xmlanyement
公共列表getXmlProperties(){
列表元素=新的ArrayList();
对于(Map.Entry属性:properties.entrySet())
添加(新的JAXBElement(新的QName(property.getKey()),
String.class,property.getValue());
返回元素;
}
这工作得很好,但我在Bean/Pojo类中使用了它,该类与GWT前端共享,因此不能包含对JAXBElement和QName的引用(需要源代码)
那么,有没有一种方法可以使用XmlAdapter和JAXBElement/QName/XmlAnyElement dream团队之类的东西获得类似的结果?顺便说一下,如果考虑到这一点,我正在使用RESTEasy
这是一篇关于@xmlanyement+JAXBElement的论坛帖子:我离答案不远了——经过一点实验,我找到了正确的组合
为不可映射的返回类型创建包装器类。包装器应该包含/return
List我离答案不远了——经过更多的实验,我找到了正确的组合
为不可映射的返回类型创建包装器类。包装器应该包含/returnList取决于上面列出的解决方案,我参与了这个MapAdapter
处理封送和反封送过程
@XmlType
public class MapWrapper{
private List<JAXBElement<String>> properties = new ArrayList<>();
public MapWrapper(){
}
@XmlAnyElement
public List<JAXBElement<String>> getProperties() {
return properties;
}
public void setProperties(List<JAXBElement<String>> properties) {
this.properties = properties;
}
@Override
public String toString() {
return "MapWrapper [properties=" + toMap() + "]";
}
public Map<String, String> 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<Class<?>, Function<? super Object, String>> strFuncs = new HashMap<>();
strFuncs.put(JAXBElement.class, (jaxb) -> ((JAXBElement<String>)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<Class<?>, Function<? super Object, String>> strFuncs = new HashMap<>();
strFuncs.put(JAXBElement.class, (jaxb) -> ((JAXBElement<String>)jaxb).getValue());
strFuncs.put(Element.class, ele -> ((Element) ele).getTextContent());
return extractPart(obj, strFuncs).orElse("");
}
private static <ObjType, T> Optional<T> extractPart(ObjType obj, Map<Class<?>, Function<? super ObjType, T>> 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<MapWrapper, Map<String, String>>{
@Override
public Map<String, String> unmarshal(MapWrapper v) throws Exception {
return v.toMap();
}
@Override
public MapWrapper marshal(Map<String, String> m) throws Exception {
MapWrapper wrapper = new MapWrapper();
for(Map.Entry<String, String> entry : m.entrySet()){
wrapper.addEntry(new JAXBElement<String>(new QName(entry.getKey()), String.class, entry.getValue()));
}
return wrapper;
}
}
@XmlType
公共类映射包装器{
私有列表属性=新的ArrayList();
公共映射包装器(){
}
@XmlAnyElement
公共列表getProperties(){
归还财产;
}
公共void集合属性(列表属性){
这个。属性=属性;
}
@凌驾
公共字符串toString(){
返回“MapWrapper[properties=“+toMap()+”]”;
}
公共地图toMap(){
//注意:由于类型擦除,在使用Unshalling时不能直接使用properties.stream()。
列出道具=属性;
返回props.stream().collect(Collectors.toMap(MapWrapper::extractLocalName,MapWrapper::extractTextContent));
}
@抑制警告(“未选中”)
私有静态字符串extractLocalName(对象obj){
Map,Function取决于上面列出的解决方案,我加入了这个MapAdapter
,它同时处理封送和解封送过程
@XmlType
public class MapWrapper{
private List<JAXBElement<String>> properties = new ArrayList<>();
public MapWrapper(){
}
@XmlAnyElement
public List<JAXBElement<String>> getProperties() {
return properties;
}
public void setProperties(List<JAXBElement<String>> properties) {
this.properties = properties;
}
@Override
public String toString() {
return "MapWrapper [properties=" + toMap() + "]";
}
public Map<String, String> 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<Class<?>, Function<? super Object, String>> strFuncs = new HashMap<>();
strFuncs.put(JAXBElement.class, (jaxb) -> ((JAXBElement<String>)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<Class<?>, Function<? super Object, String>> strFuncs = new HashMap<>();
strFuncs.put(JAXBElement.class, (jaxb) -> ((JAXBElement<String>)jaxb).getValue());
strFuncs.put(Element.class, ele -> ((Element) ele).getTextContent());
return extractPart(obj, strFuncs).orElse("");
}
private static <ObjType, T> Optional<T> extractPart(ObjType obj, Map<Class<?>, Function<? super ObjType, T>> 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<MapWrapper, Map<String, String>>{
@Override
public Map<String, String> unmarshal(MapWrapper v) throws Exception {
return v.toMap();
}
@Override
public MapWrapper marshal(Map<String, String> m) throws Exception {
MapWrapper wrapper = new MapWrapper();
for(Map.Entry<String, String> entry : m.entrySet()){
wrapper.addEntry(new JAXBElement<String>(new QName(entry.getKey()), String.class, entry.getValue()));
}
return wrapper;
}
}
@XmlType
公共类映射包装器{
私有列表属性=新的ArrayList();
公共映射包装器(){
}
@XmlAnyElement
公共列表getProperties(){
归还财产;
}
公共void集合属性(列表属性){
这个。属性=属性;
}
@凌驾
公共字符串toString(){
返回“MapWrapper[properties=“+toMap()+”]”;
}
公共地图toMap(){
//注意:由于类型擦除,在使用Unshalling时不能直接使用properties.stream()。
列出道具=属性;
返回props.stream().collect(Collectors.toMap(MapWrapper::extractLocalName,MapWrapper::extractTextContent));
}
@抑制警告(“未选中”)
私有静态字符串extractLocalName(对象obj){
Map,function你救了我一天!谢谢:)如果你添加了unmarshall函数那就太好了hi,非常感谢你的回复。我正在尝试unmarshalXML
,我不知道如何在这里实现unmarshal
方法。如果可能的话,你能为我提到的unmarshal
方法提供示例吗在MapAdapter
类中:您救了我一天!谢谢:)如果您添加了解组功能,那就太好了。hi,非常感谢您的响应。我正在尝试解组XML
,我不知道如何在这里实现unmarshal
方法。如果可能,请您提供unmarshal的示例MapAdapter
类中提到的code>方法:这在现实生活中是如何使用的?很高兴看到一个例子!这在现实生活中是如何使用的?很高兴看到一个例子!
@XmlRootElement
public class SomeBean {
@XmlJavaTypeAdapter(MapAdapter.class)
public LinkedHashMap<String, String> getProperties() {
return properties;
}
}
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>
@XmlType
public class MapWrapper{
private List<JAXBElement<String>> properties = new ArrayList<>();
public MapWrapper(){
}
@XmlAnyElement
public List<JAXBElement<String>> getProperties() {
return properties;
}
public void setProperties(List<JAXBElement<String>> properties) {
this.properties = properties;
}
@Override
public String toString() {
return "MapWrapper [properties=" + toMap() + "]";
}
public Map<String, String> 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<Class<?>, Function<? super Object, String>> strFuncs = new HashMap<>();
strFuncs.put(JAXBElement.class, (jaxb) -> ((JAXBElement<String>)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<Class<?>, Function<? super Object, String>> strFuncs = new HashMap<>();
strFuncs.put(JAXBElement.class, (jaxb) -> ((JAXBElement<String>)jaxb).getValue());
strFuncs.put(Element.class, ele -> ((Element) ele).getTextContent());
return extractPart(obj, strFuncs).orElse("");
}
private static <ObjType, T> Optional<T> extractPart(ObjType obj, Map<Class<?>, Function<? super ObjType, T>> 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<MapWrapper, Map<String, String>>{
@Override
public Map<String, String> unmarshal(MapWrapper v) throws Exception {
return v.toMap();
}
@Override
public MapWrapper marshal(Map<String, String> m) throws Exception {
MapWrapper wrapper = new MapWrapper();
for(Map.Entry<String, String> entry : m.entrySet()){
wrapper.addEntry(new JAXBElement<String>(new QName(entry.getKey()), String.class, entry.getValue()));
}
return wrapper;
}
}