在本文中,我们将为您详细介绍java–使用JAXB根据属性创建引用对象的相关知识,并且为您解答关于java根据类型创建对象的疑问,此外,我们还会提供一些关于Java/JAXB:将XML属性解组为特定的
在本文中,我们将为您详细介绍java – 使用JAXB根据属性创建引用对象的相关知识,并且为您解答关于java 根据类型创建对象的疑问,此外,我们还会提供一些关于Java / JAXB:将XML属性解组为特定的Java对象属性、Java Unmarshal使用JAXB的对象列表、java – 使用JAXB创建不可变对象、java – 使用JAXB处理丢失的节点的有用信息。
本文目录一览:- java – 使用JAXB根据属性创建引用对象(java 根据类型创建对象)
- Java / JAXB:将XML属性解组为特定的Java对象属性
- Java Unmarshal使用JAXB的对象列表
- java – 使用JAXB创建不可变对象
- java – 使用JAXB处理丢失的节点
java – 使用JAXB根据属性创建引用对象(java 根据类型创建对象)
考虑以下xml:
<Config>
<Paths>
<Path reference="WS_License"/>
</Paths>
<Steps>
<Step id="WS_License" title="License Agreement" />
</Steps>
</Config>
以下JAXB类:
public class Path {
private String _reference;
public String getReference() {
return _reference;
}
@XmlAttribute
public void setReference( String reference ) {
_reference = reference;
}
}
和
public class Step {
private String _id;
private String _title;
public String getId() {
return _id;
}
@XmlAttribute
public void setId( String id ) {
_id = id;
}
public String getTitle() {
return _title;
}
@XmlAttribute
public void setTitle( String title ) {
_title = title;
}
}
我不想将引用作为String存储在Path对象中,而是将其作为Step对象保存.这些对象之间的链接是reference和id属性. @XMLJavaTypeAdapter属性是否可行?任何人都可以如此善良地提供正确用法的例子吗?
谢谢!
编辑:
我也想用元素做同样的技术.
考虑以下xml:
<Config>
<Step id="WS_License" title="License Agreement">
<DetailPanelReference reference="DP_License" />
</Step>
<DetailPanels>
<DetalPanel id="DP_License" title="License Agreement" />
</DetailPanels>
</Config>
以下JAXB类:
@XmlAccessorType(XmlAccesstype.FIELD)
public class Step {
@XmlID
@XmlAttribute(name="id")
private String _id;
@XmlAttribute(name="title")
private String _title;
@XmlIDREF
@XmlElement(name="DetailPanelReference", type=DetailPanel.class)
private DetailPanel[] _detailPanels; //Doesn't seem to work
}
@XmlAccessorType(XmlAccesstype.FIELD)
public class DetailPanel {
@XmlID
@XmlAttribute(name="id")
private String _id;
@XmlAttribute(name="title")
private String _title;
}
Step-object中的属性_detailPanels为空,链接似乎不起作用.是否有任何选项可以在不创建仅包含对DetailPanel的引用的新JAXB对象的情况下创建链接?
再次感谢 : )!
解决方法:
您可以使用@XmlID将属性映射为键,使用@XmlIDREF将引用映射到此用例的键.
步
@XmlAccessorType(XmlAccesstype.FIELD)
public class Step {
@XmlID
@XmlAttribute
private String _id;
}
路径
@XmlAccessorType(XmlAccesstype.FIELD)
public class Path {
@XmlIDREF
@XmlAttribute
private Step _reference;
}
欲获得更多信息
> http://blog.bdoughan.com/2010/10/jaxb-and-shared-references-xmlid-and.html
UPDATE
Thanks! I Completely missed your article. I’ve extended my question,
do you have any clue if this is possible too? I do not want to create
a class with only holding the reference, I’d like to store it inside
the step class.
注意:我是EclipseLink JAXB (MOXy)领导者,也是JAXB (JSR-222)专家组的成员.
如果您使用MOXy作为JAXB(JSR-222)提供程序,那么您可以将@XmlPath批注用于您的用例.
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;
@XmlAccessorType(XmlAccesstype.FIELD)
public class Step {
@XmlID
@XmlAttribute
private String id;
@XmlPath("DetailPanelReference/@reference")
@XmlIDREF
// private List<DetailPanel> _detailPanels; // WORKS
private DetailPanel[] _detailPanels; // See bug: http://bugs.eclipse.org/399293
}
欲获得更多信息
> http://bugs.eclipse.org/399293
> http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
> http://blog.bdoughan.com/2010/07/xpath-based-mapping.html
Java / JAXB:将XML属性解组为特定的Java对象属性
有一个丑陋的XML文件必须解组:
<?xml version="1.0" ?><configuration> <section name="default_options"> <value name="default_port">8081</value> <value name="log_level">WARNING</value> </section> <section name="custom_options"> <value name="memory">64M</value> <value name="compatibility">yes</value> </section></configuration>
产生的Java对象应为:
public class DefaultOptions { private int defaultPort; private String logLevel; // etc...}public class CustomOptions { private String memory; private String compatibility; // etc...}
这个问题的答案非常接近,但我不知道最终的解决方案。
答案1
小编典典怎么样?
介绍一个称为选项的通用超类:
import javax.xml.bind.annotation.XmlAttribute;public abstract class Options { private String name; @XmlAttribute public String getName() { return name; } public void setName(String name) { this.name = name; }}
然后在带有选项列表的类(在本示例中为Configuration)上,在该属性上指定一个@XmlJavaTypeAdapter:
import java.util.ArrayList;import java.util.List;import javax.xml.bind.annotation.XmlRootElement;import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;@XmlRootElementpublic class Configuration { private List<Options> section = new ArrayList<Options>(); @XmlJavaTypeAdapter(OptionsAdapter.class) public List<Options> getSection() { return section; } public void setSection(List<Options> section) { this.section = section; }}
XmlAdapter看起来像这样:
import javax.xml.bind.annotation.adapters.XmlAdapter;public class OptionsAdapter extends XmlAdapter<AdaptedOptions, Options> { @Override public Options unmarshal(AdaptedOptions v) throws Exception { if("default_options".equals(v.name)) { DefaultOptions options = new DefaultOptions(); options.setName(v.getName()); options.setDefaultPort(Integer.valueOf(v.map.get("default_port"))); options.setLogLevel(v.map.get("log_level")); return options; } else { CustomOptions options = new CustomOptions(); options.setName(v.getName()); options.setCompatibility(v.map.get("compatibility")); options.setMemory(v.map.get("memory")); return options; } } @Override public AdaptedOptions marshal(Options v) throws Exception { AdaptedOptions adaptedOptions = new AdaptedOptions(); adaptedOptions.setName(v.getName()); if(DefaultOptions.class == v.getClass()) { DefaultOptions options = (DefaultOptions) v; adaptedOptions.map.put("default_port", String.valueOf(options.getDefaultPort())); adaptedOptions.map.put("log_level", options.getLogLevel()); } else { CustomOptions options = (CustomOptions) v; adaptedOptions.map.put("compatibility", options.getCompatibility()); adaptedOptions.map.put("memory", options.getMemory()); } return adaptedOptions; }}
AdaptedOptions看起来像:
import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Map.Entry;import javax.xml.bind.Marshaller;import javax.xml.bind.Unmarshaller;import javax.xml.bind.annotation.XmlAttribute;import javax.xml.bind.annotation.XmlElement;import javax.xml.bind.annotation.XmlValue;public class AdaptedOptions extends Options { @XmlAttribute String name; @XmlElement List<Value> value = new ArrayList<Value>(); Map<String, String> map = new HashMap<String, String>(); public void beforeMarshal(Marshaller marshaller) { for(Entry<String, String> entry : map.entrySet()) { Value aValue = new Value(); aValue.name = entry.getKey(); aValue.value = entry.getValue(); value.add(aValue); } } public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) { for(Value aValue : value) { map.put(aValue.name, aValue.value); } } private static class Value { @XmlAttribute String name; @XmlValue String value; }}
Java Unmarshal使用JAXB的对象列表
我有看起来像下面的XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ObjectList>
<object attributeOne="somedate" attributeTwo="false" attributeThree="id" attributeFour="true"/>
<object attributeOne="somedate" attributeTwo="false" attributeThree="id" attributeFour="true"/>
<object attributeOne="somedate" attributeTwo="false" attributeThree="id" attributeFour="true"/>
<object attributeOne="somedate" attributeTwo="false" attributeThree="id" attributeFour="true"/>
<object attributeOne="somedate" attributeTwo="false" attributeThree="id" attributeFour="true"/>
</ObjectList>
我有一个如下的ObjectList类:
@XmlRootElement
public class ObjectList {
@XmlElementWrapper(name = "ObjectList")
@XmlElement(name = "Object")
private ArrayList<Object> ObjectList;
public ArrayList<Object> getObjectList() {
return ObjectList;
}
public void setObjectList(ArrayList<Object> objectList) {
ObjectList = objectList;
}
}
还有一个对象类,如下所示:
@XmlRootElement(name = "Object")
public class Object {
Date attributeOne;
boolean attritbuteTwo;
String attributeThree;
boolean attributeFour;
@XmlAttribute
public Date getAttributeOne() {
return attributeOne;
}
public void setAttributeOne(Date attributeOne) {
this.attributeOne = attributeOne;
}
@XmlAttribute
public boolean isAttributeTwo() {
return attritbuteTwo;
}
public void setAttributeTwo(boolean attritbuteTwo) {
this.AttributeTwo = AttributeTwo;
}
@XmlAttribute
public String getAttributeThree() {
return attributeThree;
}
public void setAttributeThree(String attributeThree) {
this.attributeThree = attributeThree;
}
@XmlAttribute
public boolean isAttributeFour() {
return attributeFour;
}
public void setAttributeFour(boolean attributeFour) {
this.attributeFour = attributeFour;
}
}
当我尝试使用以下代码将xml解组为和对象时:
JAXBContext jaxbContext = JAXBContext.newInstance(ObjectList.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
RESTResponse response = getObjects();
ObjectList objects = (ObjectList) unmarshaller.unmarshal(new StringReader(response.getResponseBody()));
我收到以下错误:
javax.xml.bind.UnmarshalException:意外元素(uri:“”,本地:“ ObjectList”)。期望的元素是<{}
Object>,<{} objectList>
编辑: 我只是注意到几个问题,我将ObjectList对象的XmlRootElement标记更改为@XmlRootElement(name =“
ObjectList”),将我对象的XmlRootElement标记更改为@XmlRootElement(name =“
object)。我不再得到异常,但是我现在得到并清空对象列表。
任何帮助深表感谢。
java – 使用JAXB创建不可变对象
目前,我将这些不可变换的包装器归还给客户端应用程序.是否有任何选项,以便自动生成的类将是不可变的,它将避免创建不可变的包装器的额外工作.鼓励任何其他方法.
>谢谢
解决方法
然后,如果调用以“set”开头的方法,则可以抛出异常.
这是一个可重用的类,可以包装“任何”POJO的方法:
import java.lang.reflect.Method; import javassist.util.proxy.MethodFilter; import javassist.util.proxy.MethodHandler; import javassist.util.proxy.Proxy; import javassist.util.proxy.ProxyFactory; public class Utils { public static <C> C createInmutableBean(Class<C> clazz,final C instance) throws InstantiationException,illegalaccessexception { if (!clazz.isAssignableFrom(instance.getClass())) { throw new IllegalArgumentException("given instance of class " + instance.getClass() + " is not a subclass of " + clazz); } ProxyFactory f = new ProxyFactory(); f.setSuperclass(clazz); f.setFilter(new MethodFilter() { public boolean isHandled(Method m) { // ignore finalize() return !m.getName().equals("finalize"); } }); Class c = f.createClass(); MethodHandler mi = new MethodHandler() { public Object invoke(Object self,Method m,Method proceed,Object[] args) throws Throwable { if (m.getName().startsWith("set")) { throw new RuntimeException("this bean is inmutable!"); } return m.invoke(instance,args); // execute the original method // over the instance } }; C proxy = (C) c.newInstance(); ((Proxy) proxy).setHandler(mi); return (C) proxy; } }
这里是一个示例代码.让员工成为你的豆子:
public class Employee{ private String name="John"; private String surname="Smith"; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSurname() { return surname; } public void setSurname(String surname) { this.surname = surname; } };
这里有一个测试用例,表明您可以为POJO创建一个代理,使用它的getter,但是不能使用它的setter
@Test public void testProxy() throws InstantiationException,illegalaccessexception{ Employee aBean = new Employee(); //I can modify the bean aBean.setName("Obi-Wan"); aBean.setSurname("Kenobi"); //create the protected java bean with the generic utility Employee protectedBean = Utils.createInmutableBean(Employee.class,aBean); //I can read System.out.println("Name: "+protectedBean.getName()); System.out.println("Name: "+protectedBean.getSurname()); //but I can't modify try{ protectedBean.setName("Luke"); protectedBean.setSurname("Skywalker"); throw new RuntimeException("The test should not have reached this line!"); }catch(Exception e){ //I should be here System.out.println("The exception was expected! The bean should not be modified (exception message: "+e.getMessage()+")"); assertEquals("Obi-Wan",protectedBean.getName()); assertEquals("Kenobi",protectedBean.getSurname()); } }
java – 使用JAXB处理丢失的节点
<root> <firstChild>12/12/2012</firstChild> <secondChild> <firstGrandChild> <Id> </name> <characteristics>Description</characteristics> <code>12345</code> </Id> </firstGrandChild> </secondChild> </root>
我面临以下两种情况:
>节点< name>存在于生成的类中但不存在于XML文件中
>节点没有值
在这两种情况下,该值都设置为null.我希望能够区分XML文件中何时不存在该节点以及何时存在但具有空值的节点.尽管我的搜索,我还没有想出办法.任何帮助都非常受欢迎
非常感谢您的时间和帮助
问候
解决方法
public class Foo { private String bar; private boolean barSet = false; public String getBar() { return bar; } public void setBar(String bar) { this.bar = bar; this.barSet = true; } }
UPDATE
JAXB还将空节点视为具有空String的值.
Java模型
import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Root { private String foo; private String bar; public String getFoo() { return foo; } public void setFoo(String foo) { this.foo = foo; } public String getBar() { return bar; } public void setBar(String bar) { this.bar = bar; } }
演示
import java.io.File; import javax.xml.bind.*; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Root.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); File xml = new File("src/forum15839276/input.xml"); Root root = (Root) unmarshaller.unmarshal(xml); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true); marshaller.marshal(root,System.out); } }
input.xml中/输出
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <root> <foo></foo> </root>
关于java – 使用JAXB根据属性创建引用对象和java 根据类型创建对象的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于Java / JAXB:将XML属性解组为特定的Java对象属性、Java Unmarshal使用JAXB的对象列表、java – 使用JAXB创建不可变对象、java – 使用JAXB处理丢失的节点等相关内容,可以在本站寻找。
本文标签: