我正在尝试使用JAXB 2.2.4将接口序列化为XML,但是当我在Map <>对象中有一个接口时,它会爆炸并给我错误:
com.sun.xml.bind.v2.runtime.IllegalAnnotationsException:IllegalAnnotationExceptions的2个计数com.test.IInterface2是一个接口,JAXB无法处理接口.此问题与以下位置有关:at com.test.IInterface2 at public java.util.Map com.test.Interface1Impl.getI2()at com.test.Interface1Impl com.test.IInterface2没有no-arg默认值构造函数.此问题与以下位置有关:在com.test.Interface1Impl上的公共java.util.Map com.test.Interface1Impl.getI2()中的com.test.IInterface2处
如果我删除了Map <>,这个代码已经过测试并且有效,如果我使用List <>,它甚至可以使用它,但是有一些关于JAXB不喜欢的Map <>.
这是我正在运行的代码,如果您知道解决此问题的方法,请告诉我!
package com.test;
import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlSeeAlso;
@XmlSeeAlso({Interface2Impl.class})
public class main
{
/**
* @param args
*/
public static void main(String[] args) {
IInterface1 i1 = new Interface1Impl();
i1.setA("SET A VALUE");
i1.setB("Set B VALUE");
IInterface2 i2 = new Interface2Impl();
i2.setC("X");
i2.setD("Y");
i1.getI2().put("SOMVAL",i2);
String retval = null;
try {
StringWriter writer = new StringWriter();
JAXBContext context = JAXBContext.newInstance(Interface1Impl.class, Interface2Impl.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(i1, writer);
retval = writer.toString();
} catch (JAXBException ex) {
//TODO: Log the error here!
retval = ex.toString();
}
System.out.println(retval);
}
}
Run Code Online (Sandbox Code Playgroud)
package com.test;
import java.util.Map;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.sun.xml.bind.AnyTypeAdapter;
@XmlRootElement
@XmlJavaTypeAdapter(AnyTypeAdapter.class)
public interface IInterface1
{
Map<String,IInterface2> getI2();
String getA();
String getB();
void setA(String a);
void setB(String b);
void setI2(Map<String,IInterface2> i2);
}
Run Code Online (Sandbox Code Playgroud)
package com.test;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Interface1Impl implements IInterface1
{
Map<String,IInterface2> i2 = new HashMap<String,IInterface2>();
String a;
String b;
public Interface1Impl()
{
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public Map<String,IInterface2> getI2() {
return i2;
}
public void setI2(Map<String,IInterface2> i2) {
this.i2 = i2;
}
}
Run Code Online (Sandbox Code Playgroud)
package com.test;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.sun.xml.bind.AnyTypeAdapter;
@XmlRootElement
@XmlJavaTypeAdapter(AnyTypeAdapter.class)
public interface IInterface2
{
String getC();
String getD();
void setC(String c);
void setD(String d);
}
Run Code Online (Sandbox Code Playgroud)
package com.test;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Interface2Impl implements IInterface2
{
String c;
String d;
public Interface2Impl()
{
}
public String getC() {
return c;
}
public void setC(String c) {
this.c = c;
}
public String getD() {
return d;
}
public void setD(String d) {
this.d = d;
}
}
Run Code Online (Sandbox Code Playgroud)
要获得以下输出,您可以执行以下操作(请参阅下文):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<interface1Impl>
<a>SET A VALUE</a>
<b>Set B VALUE</b>
<i2>
<entry>
<key>SOMVAL</key>
<value>
<c>X</c>
<d>Y</d>
</value>
</entry>
</i2>
</interface1Impl>
Run Code Online (Sandbox Code Playgroud)
I2Adapter
我们将使用一个XmlAdapter来处理Map<String, IInterface2>.An XmlAdapter是一种JAXB机制,它将JAXB无法映射的对象转换为可以映射的对象.
package com.test;
import java.util.*;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class I2Adapter extends XmlAdapter<I2Adapter.AdaptedI2, Map<String, IInterface2>> {
@Override
public AdaptedI2 marshal(Map<String, IInterface2> v) throws Exception {
if(null == v) {
return null;
}
AdaptedI2 adaptedI2 = new AdaptedI2();
for(Map.Entry<String,IInterface2> entry : v.entrySet()) {
adaptedI2.entry.add(new Entry(entry.getKey(), entry.getValue()));
}
return adaptedI2;
}
@Override
public Map<String, IInterface2> unmarshal(AdaptedI2 v) throws Exception {
if(null == v) {
return null;
}
Map<String, IInterface2> map = new HashMap<String, IInterface2>();
for(Entry entry : v.entry) {
map.put(entry.key, entry.value);
}
return map;
}
public static class AdaptedI2 {
public List<Entry> entry = new ArrayList<Entry>();
}
public static class Entry {
public Entry() {
}
public Entry(String key, IInterface2 value) {
this.key = key;
this.value = value;
}
public String key;
@XmlElement(type=Interface2Impl.class)
public IInterface2 value;
}
}
Run Code Online (Sandbox Code Playgroud)
Interface1Impl
该@XmlJavaTypeAdapter注释被用于注册XmlAdapter.在这个例子中,我们将在i2属性上注册它.
package com.test;
import java.util.*;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
public class Interface1Impl implements IInterface1 {
Map<String, IInterface2> i2 = new HashMap<String, IInterface2>();
String a;
String b;
public Interface1Impl() {
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
@XmlJavaTypeAdapter(I2Adapter.class)
public Map<String, IInterface2> getI2() {
return i2;
}
public void setI2(Map<String, IInterface2> i2) {
this.i2 = i2;
}
}
Run Code Online (Sandbox Code Playgroud)
欲获得更多信息
下面是模型的其余部分,其中从非模型类中删除了JAXB注释:
主要
package com.test;
import java.io.StringWriter;
import javax.xml.bind.*;
public class main {
/**
* @param args
*/
public static void main(String[] args) {
IInterface1 i1 = new Interface1Impl();
i1.setA("SET A VALUE");
i1.setB("Set B VALUE");
IInterface2 i2 = new Interface2Impl();
i2.setC("X");
i2.setD("Y");
i1.getI2().put("SOMVAL", i2);
String retval = null;
try {
StringWriter writer = new StringWriter();
JAXBContext context = JAXBContext.newInstance(Interface1Impl.class,
Interface2Impl.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(i1, writer);
retval = writer.toString();
} catch (JAXBException ex) {
// TODO: Log the error here!
retval = ex.toString();
}
System.out.println(retval);
}
}
Run Code Online (Sandbox Code Playgroud)
IInterface1
package com.test;
import java.util.Map;
public interface IInterface1 {
Map<String, IInterface2> getI2();
String getA();
String getB();
void setA(String a);
void setB(String b);
void setI2(Map<String, IInterface2> i2);
}
Run Code Online (Sandbox Code Playgroud)
IInterface2
package com.test;
public interface IInterface2 {
String getC();
String getD();
void setC(String c);
void setD(String d);
}
Run Code Online (Sandbox Code Playgroud)
Interface2Impl
package com.test;
public class Interface2Impl implements IInterface2 {
String c;
String d;
public Interface2Impl() {
}
public String getC() {
return c;
}
public void setC(String c) {
this.c = c;
}
public String getD() {
return d;
}
public void setD(String d) {
this.d = d;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8660 次 |
| 最近记录: |