jaxb中的类继承

7 篇文章 0 订阅
6 篇文章 0 订阅

jersey中的@Produces(“application/xml”)是由jaxb来负责处理的,只要项目中引入了jaxb-api-2.2.7.jar.所以只要注解使用对了,在jersey中输出xml文件是不需要单独写@Provider处理器的。单个类你只要在类上加入@XmlRootElement注解,jaxb会把它换成xml输出。

@XmlRootElement
public class Address implements Serializable{
}

简单吧。但项目中不是所有的类都是独立存在的,它可能实现接口或继续某个父类。
来看一个jersey中可能存在的场景:客户端需要分页浏览记录(某个对象列表),一般要分页可能要作两件事
1.获得总数量或者记录的最大id值(此时自增列不能出现裂带)

int getArticleSize();

2.获得某页的数据

List<Article> getArticleForPage(int page,int pageSize);

为了减少网络请求数量可以把1,2封装到一个结果集中.不论是否存在记录都假定它有一页的记录量

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="articleResult")
public class ArticleQueryList implements Serializable{

    private static final long serialVersionUID = 1L;
    //总数量
    @XmlElement
    int total;
    //结果集
    @XmlElementWrapper
    @XmlElement(name="article")
    List<Article> result;
    //查询参数
    @XmlElement
    String param;
    //页码
    @XmlElement
    int page;
    //每页数量
    @XmlElement
    int pageSize;
}

@XmlAccessorType(XmlAccessType.FIELD)为默认注解可以不用写,像上面的Address类虽然没有加此注解,但不能当它不存在.

注意:如果加了XmlAccessType.FIELD类注解,此时出现下面的代码

    @XmlElementWrapper(name="result")
    @XmlElement(name="article")
    List<Article> result;

jaxb会出错,提示:Class has two properties of the same name “result”

如果项目有很多个不同的查询列表,不可能一个对象查询列表写一个类,需要抽像一下,把page,pageSize,param移到一个抽像的父类中,而具体的对象列表归到一个子类中.

@XmlSeeAlso({
    ArticleQueryList.class,
    ChannelQueryList.class})
public abstract class QueryList<T> implements Serializable{
    private static final long serialVersionUID = 1L;
    //总数量
    protected int total;
    //结果集
    protected List<T> result;
    //查询参数
    @XmlElement
    private String param;
    //页码
    @XmlElement
    private int page;
    //每页数量
    @XmlElement
    private int pageSize;

    public abstract List<T> getResult();
    public abstract void setResult(List<T> result);
    public abstract void setTotal(int total); 
    public abstract int getTotal();
}

一个具体的文章查询列表

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="articleResult")
public class ArticleQueryList extends QueryList<Article>{

    private static final long serialVersionUID = 1L;

    @XmlElementWrapper
    @XmlElement(name="article")
    @Override
    public List<Article> getResult() {
        // TODO Auto-generated method stub
        return super.result;
    }
    @Override
    public void setResult(List<Article> result) {
        // TODO Auto-generated method stub
        super.result=result;
    }
    @Override
    public void setTotal(int total) {
        // TODO Auto-generated method stub
        super.total=total;
    }
    @XmlElement
    @Override
    public int getTotal() {
        // TODO Auto-generated method stub
        return super.total;
    }

}

运行会出错:

Class has two properties of the same name "page"
    this problem is related to the following location:
        at public int net.project.query.QueryList.getPage()
        at net.project.query.QueryList
        at net.project.query.ArticleQueryList
    this problem is related to the following location:
        at private int net.project.query.QueryList.page
        at net.project.query.QueryList
        at net.project.query.ArticleQueryList
Class has two properties of the same name "pageSize"
    this problem is related to the following location:
        at public int net.project.query.QueryList.getPageSize()
        at net.project.query.QueryList
        at net.project.query.ArticleQueryList
    this problem is related to the following location:
        at private int net.project.query.QueryList.pageSize
        at net.project.query.QueryList
        at net.project.query.ArticleQueryList
Class has two properties of the same name "param"
    this problem is related to the following location:
        at public java.lang.String net.project.query.QueryList.getParam()
        at net.project.query.QueryList
        at net.project.query.ArticleQueryList
    this problem is related to the following location:
        at private java.lang.String net.project.query.QueryList.param
        at net.project.query.QueryList
        at net.project.query.ArticleQueryList

因为QueryList上有默认的@XmlAccessorType(XmlAccessType.FIELD)注解,而ArticleQueryList上显式的类注解,导致了jaxb认为出现了两个param,page,pageSize.

知道了问题出在哪,修复就容易了.

@XmlSeeAlso({
    ArticleQueryList.class,
    ChannelQueryList.class})
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement
public abstract class QueryList<T> implements Serializable{}

再运行就可以输出希望的xml

<articleResult>
    <param>date:today</param>
    <page>1</page>
    <pageSize>30</pageSize>
    <result>
        <article>
            <id>1966</id><hash>55b32556218b4a871e1cd386bccbb57b</hash> <source>ifanr.com</source>
            <status>true</status>
            <date>2015-11-21T11:17:27+08:00</date>
            <title>沃尔沃的 Concept 26:要自动驾驶,也要驾驶乐趣</title>
            <link>http://www.ifanr.com/587368?utm_source=rss&utm_medium=rss&utm_campaign=</link>
       </article>
       <!--//ETC -->
    </result>
    <total>180</total>
</articleResult>

总结:
1.如果注解的类中属性不是全部输出,一定要不要使用
@XmlAccessorType(XmlAccessType.FIELD)
或者不写@XmlAccessorType

2.@XmlSeeAlso不仅可以用于继续关系还可以用于实现关系

3.@XmlElement(name=”值”)值如果与属性名一致不要写括号内的别名

4.不希望属性输出可以使用@XmlTransient注解,例:

@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement
public class Channel implements Serializable{

    private static final long serialVersionUID = 1L;

    @XmlElement
    int id;
    @XmlElement
    String name;
    @XmlElement
    URL url;
    /**
     * 编码
     */
    @XmlTransient
    String encode;
}

5.jaxb其它的注解
可以访问:jaxb@java.net
下载api文档和jaxb-api.jar
中文:oracle@xmlbind.javase6
常用的注解:
@XmlType(propOrder={“street”, “city” , “state”, “zip”, “name” })
指定xml中属性的排序
@XmlAttribute
指定为元素的属性

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
抱歉,我是一名AI语言模型,无法编写具体的代码。不过我可以提供一份通用的jaxb工具模板,供您参考: ```java import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.bind.Marshaller; import java.io.File; public class JAXBUtils { /** * xml转JavaBean对象 * @param <T> 对象型 * @param xmlFile xml文件 * @param tClazz 对象class型 * @return 对象 * @throws JAXBException JAXB异常 */ public static <T> T xml2Bean(File xmlFile, Class<T> tClazz) throws JAXBException { T t = null; JAXBContext jaxbContext = JAXBContext.newInstance(tClazz); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); t = (T) jaxbUnmarshaller.unmarshal(xmlFile); return t; } /** * JavaBean对象xml * @param obj 对象 * @param xmlFile xml文件 * @throws JAXBException JAXB异常 */ public static void bean2Xml(Object obj, File xmlFile) throws JAXBException { JAXBContext jaxbContext = JAXBContext.newInstance(obj.getClass()); Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(obj, xmlFile); } } ``` 使用示例: ```java public static void main(String[] args) { try { // xml文件转JavaBean对象 File xmlFile = new File("test.xml"); User user = JAXBUtils.xml2Bean(xmlFile, User.class); System.out.println(user.toString()); // JavaBean对象xml文件 File newXmlFile = new File("newtest.xml"); JAXBUtils.bean2Xml(user, newXmlFile); } catch (JAXBException e) { e.printStackTrace(); } } ``` 其,User为自定义的JavaBean对象,test.xmlxml文件,newtest.xml为输出的xml文件。具体实现时,需要根据自己的需求修改部分实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值