求大神路过,JAXB怎样处理动态集合啊?

snzke 2012-04-16 10:54:43
就是当我用JAXB转xml字符串为java对象时,里面包含有集合对象。但是集合对象中的类型又不固定。

我想用java的多态来实现,但是好像JAXB并不能识别。

简单核心代码如下:


import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import com.keer.common.domain.ListBean;
import com.keer.common.domain.Person;

public class Test{

private JdbcTemplate jdbcTemplate;

//这是Test类型
public String getAc01All() {
String sql ="select aac001,aac002,aac003 from ac01";
List<Person> list = jdbcTemplate.query(sql, new RowMapper<Person>(){
public Person mapRow(ResultSet rs, int rowNum) throws SQLException {
Person p = new Person();
p.setAac001(rs.getString("aac001"));
p.setAac002(rs.getString("aac002"));
p.setAac003(rs.getString("aac003"));
return p;
}
});
ListBean<Person> lb = new ListBean<Person>();

String s =list2XML(lb.getClass(),list);

System.out.println(s);
return s;
}


public String list2XML(Class<?> cla,List<?> list,Class<?> clas){
StringWriter writer = new StringWriter();
ListBean lb =null;
try {

Object o=cla.newInstance();
if(o instanceof ListBean){
lb = (ListBean)o;
lb.setList(list);
}
JAXBContext context = null;
if(null != clas){
context = JAXBContext.newInstance(cla,clas);
}else{
context = JAXBContext.newInstance(cla);
}

marshallXmlType(lb, writer);
} catch (Exception e) {
e.printStackTrace();
}
return writer.toString();
}


public static <T> void marshallXmlType(T value, Writer os) {
try {
Class<T> clzz = (Class<T>)value.getClass();
JAXBContext context = JAXBContext.newInstance(clzz);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.FALSE);
m.setAdapter(ListAdapter.class,new ListAdapter<Person>());
QName name = new QName(clzz.getSimpleName());
JAXBElement<T> element = new JAXBElement<T>(name, clzz, value);
m.marshal(element, os);
} catch (JAXBException e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
System.out.println(new PersonInfo().getAc01All());
}
}

//List模型类

import java.util.List;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement(name = "ListBean")
public class ListBean<T> {

private String name;
private List<T> list;

@XmlJavaTypeAdapter(ListAdapter.class)
public List<T> getList() {
return list;
}

public void setList(List<T> list) {
this.list = list;
}

@XmlAttribute
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

//模型类

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "Person")
public class Person extends Domain {

@XmlElement(required = true)
protected String aac001;
@XmlElement(required = true)
protected String aac002;
@XmlElement(required = true)
protected String aac003;
}

//xml2集合转换类
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class ListAdapter<T extends Domain> extends XmlAdapter<Domain [], List<Domain>> {

public T [] marshal(List<Domain> domains) throws Exception {
Domain [] dos = new Domain[domains.size()];
int i = 0;
for (Domain domain : domains) {
dos[i++] = domain;
System.out.println(domain.getClass().getSimpleName());
}
return (T[]) dos;
}

public List<Domain> unmarshal(Domain [] paramValueType) throws Exception {
List<Domain> list = new ArrayList<Domain>();
for (Domain domain : list) {
list.add(domain);
}
return list;
}
}

//抽象模型类

import java.io.Serializable;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "Domain")
public class Domain implements Serializable {
private static final long serialVersionUID = -3851152784887793734L;
}



期望输出的xml格式内容为:


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ListBean>
<Domain>
<aac001>3001415720</aac001>
<aac002>542336197608166802</aac002>
<aac003>巴桑</aac003>
</Domain>
<Domain>
<aac001>3001415721</aac001>
<aac002>542336196407126826</aac002>
<aac003>罗布卓玛</aac003>
</Domain>
<Domain>
<aac001>3001415722</aac001>
<aac002>542336196507030020</aac002>
<aac003>普珍</aac003>
</Domain>
</ListBean>


但是现在代码的输出是这样:


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ListBean>
<list>
<item/>
<item/>
<item/>
</list>
</ListBean>
...全文
310 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
snzke 2012-04-17
  • 打赏
  • 举报
回复
谢谢你啦 cseu 。问题解决了,原来是我的Person对象里面有多余的注解,而且转换方式也不一样。现在好了。真心感谢你!
cseu 2012-04-16
  • 打赏
  • 举报
回复
基于你的代码

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;

@XmlRootElement(name = "ListBean")
public class ListBean<T> {

private String name;
private List<T> list;

@XmlElement(name = "Domain")
public List<T> getList() {
return list;
}

public void setList(List<T> list) {
this.list = list;
}

@XmlAttribute
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}


import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;

public class Test {
public static void main(String[] args) {
Person person = new Person();
person.aac001="aac001";
person.aac002="aac002";
person.aac003="aac003";

List<Person> personList = new ArrayList<Person>();
personList.add(person);

ListBean<Person> listBean = new ListBean<Person>();
listBean.setList(personList);

try {
JAXBContext context = JAXBContext.newInstance(ListBean.class, Person.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
m.marshal(listBean,outputStream);
System.out.println(outputStream);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}

其他Domain,Person类一样
我这里跑出来结果是

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ListBean>
<Domain xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="person">
<aac001>aac001</aac001>
<aac002>aac002</aac002>
<aac003>aac003</aac003>
</Domain>
</ListBean>
snzke 2012-04-16
  • 打赏
  • 举报
回复
大神啊我照你说的那样做了,但是要报错:

[javax.xml.bind.JAXBException: class com.keer.common.domain.Person nor any of its super class is known to this context.]


你能不能写一个小小的demo啊,小demo就行了,谢谢
cseu 2012-04-16
  • 打赏
  • 举报
回复
泛型类型是可以识别的
要达到你的效果,可以这样改
in ListBean

@XmlElement(name = "Domain")
public List<T> getList() {
return list;
}

获取JAXBContext时,

JAXBContext context = JAXBContext.newInstance(ListBean.class,Person.class);

其他不必要的代码都可以删除

50,523

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧