jaxb中的类继承

来源:互联网 发布:steam 在mac上打不开 编辑:程序博客网 时间:2024/05/22 06:20

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

@XmlRootElementpublic 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.ArticleQueryListClass 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.ArticleQueryListClass 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)@XmlRootElementpublic 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)@XmlRootElementpublic 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
指定为元素的属性

0 0
原创粉丝点击