JAXB注解的使用

JDK9以下使用无需引入,jdk9以上需要引入jar包

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
</dependency>

一:常用注解

  • @XmlRootElement

  • @XmlElement

  • @XmlAttribute

  • @XmlTransient

  • @XmlAccessorType

  • @XmlAccessorOrder

  • @XmlElementWrapper

  • @XmlJavaTypeAdapter

  • @XmlValue

  • @XmlType

二:工具类


import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;

/**
 * @描述:
 * @Date: 2023/2/23 10:41
 * @Description: // PC002
 * @Author: Duys
 **/
@Slf4j
public class JaxbUtil {


    /**
     * xml转换成JavaBean
     *
     * @param xml
     * @param c
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T converyToJavaBean(String xml, Class<T> c) {
        T t = null;
        try {
            JAXBContext context = JAXBContext.newInstance(c);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            t = (T) unmarshaller.unmarshal(new StringReader(xml));
        } catch (Exception e) {
            e.printStackTrace();
            log.error("XML转Java异常.原因:{}", e.getMessage());
        }

        return t;
    }

    /**
     * JavaBean转换成xml去除xml声明部分
     *
     * @param obj
     * @param encoding
     * @return
     */
    public static String convertToXmlIgnoreXmlHead(Object obj, String encoding) {
        String result = null;
        try {
            JAXBContext context = JAXBContext.newInstance(obj.getClass());
            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
            StringWriter writer = new StringWriter();
            marshaller.marshal(obj, writer);
            result = writer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    } 

}

三:注解使用

  • @XmlRootElement

将Java类或枚举映射成XML元素根节点,是唯一一个必须注解,name属性指定根节点名称,不指定默认为类名的小写;



import lombok.Data;

import javax.xml.bind.annotation.XmlRootElement;

/**
 * @描述: 测试类
 * @Date: 2023/3/8 13:50
 * @Description: // PC002
 * @Author: Duys
 **/
@Data
@XmlRootElement(name = "test")
public class TestVo {

    private String age;

}



import cn.hutool.json.JSONUtil;
import com.jfsoft.interfaces.core.service.LisInterfaceService;
import com.jfsoft.interfaces.entity.his.vo.Reqxml;
import com.jfsoft.interfaces.entity.his.vo.TestVo;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;


@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class LisTest {
@Test
    public void test1() {

        TestVo vo = new TestVo();
        vo.setAge("50");
        String xml = JaxbUtil.convertToXmlIgnoreXmlHead(vo, "utf-8");
        log.info("xml >>> {}", xml);
    }
}

生成的
xml >>>
 <test>
    <age>50</age>
</test>
  • @XmlElement

将Java类的一个属性映射为XML节点元素,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;

/**
 * @描述: 测试类
 * @Date: 2023/3/8 13:50
 * @Description: // PC002
 * @Author: Duys
 **/
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlRootElement(name = "test")
public class TestVo {



    private String age;

    public String getAge() {
        return age;
    }

    @XmlElement(name = "ageFull")
    public void setAge(String age) {
        this.age = age;
    }
}


import com.jfsoft.interfaces.entity.his.vo.TestVo;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.StringWriter;

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class LisTest {

    @Test
    public void test0002() {

        TestVo vo = new TestVo();
        vo.setAge("50岁");
        String xml = JaxbUtil.convertToXmlIgnoreXmlHead(vo, "utf-8");
        log.info("xml >>> {}", xml);

    }

}

xml >>>
<test>
    <ageFull>50岁</ageFull>
</test>
  • @XmlAttribute

将Java类的一个属性映射为XML节点元素的属性,name属性可自定义属性名;



import javax.xml.bind.annotation.*;

/**
 * @描述: 测试类
 * @Date: 2023/3/8 13:50
 * @Description: // PC002
 * @Author: Duys
 **/
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlRootElement(name = "test")
public class TestVo {


    private String age;

    public String getAge() {
        return age;
    }

    @XmlAttribute(name = "value")
    public void setAge(String age) {
        this.age = age;
    }

}


import com.jfsoft.interfaces.entity.his.vo.TestVo;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class LisTest {

    @Test
    public void test0002() {

        TestVo vo = new TestVo();
        vo.setAge("50岁");
        String xml = JaxbUtil.convertToXmlIgnoreXmlHead(vo, "utf-8");
        log.info("xml >>> {}", xml);

    }


}

<test value="50岁"/>
  • @XmlValue

字段和方法级别的注解,简单理解就是定义xml元素文本值的类型



import lombok.Data;

import javax.xml.bind.annotation.*;

/**
 * @描述: 测试类
 * @Date: 2023/3/8 13:50
 * @Description: // PC002
 * @Author: Duys
 **/
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "test")
public class TestVo {




    @XmlAttribute(name = "value")
    private String age;

    @XmlValue
    private String value;


}



import com.jfsoft.interfaces.entity.his.vo.TestVo;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class LisTest {

    @Test
    public void test0002() {

        TestVo vo = new TestVo();
        vo.setAge("50岁");
        vo.setValue("11");
        String xml = JaxbUtil.convertToXmlIgnoreXmlHead(vo, "utf-8");
        log.info("xml >>> {}", xml);

    }


}

xml >>> <test value="50岁">11</test>
  • @XmlType

将Java类或枚举类型映射到XML模式类型,常与@XmlRootElement、@XmlAccessorType共用,propOrder属性定义字段生成的XML节点顺序;



import lombok.Data;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

/**
 * @描述: 测试类
 * @Date: 2023/3/8 13:50
 * @Description: // PC002
 * @Author: Duys
 **/
@Data
//@XmlAccessorType(XmlAccessType.FIELD) // XmlAccessType.FIELD ,属性名称须保持一致
@XmlRootElement(name = "test")
@XmlType(propOrder = {"value", "AGE"}) // 使用XmlAccessType.PUBLIC_MEMBER 访问时,propOrder属性中的条目对应于属性名称
public class TestVo {

    private String age;

    private String value;

    public String getAGE() {
        return age;
    }

    public void setAGE(String age) {
        this.age = age;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}


import com.jfsoft.interfaces.entity.his.vo.TestVo;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class LisTest {

    @Test
    public void test0002() {
        TestVo vo = new TestVo();
        vo.setAGE("50岁");
        vo.setValue("11");
        String xml = JaxbUtil.convertToXmlIgnoreXmlHead(vo, "utf-8");
        log.info("xml >>> {}", xml);

    }
}

xml >>> 
<test>
    <value>11</value>
    <AGE>50岁</AGE>
</test>
  • @XmlAccessorType

控制字段或属性的序列化。该注解只有一个value属性,可取的值是一个名为XmlAccessType的枚举类型里的值

  1. XmlAccessType.FIELD:表示JAXB将自动绑定Java类中的每个非静态的(static)、非瞬态的(由@XmlTransient标注)字段到XML

  1. XmlAccessType.PROPERTY表示java对象中所有通过getter/setter方式绑定成属性到XML

  1. XmlAccessType.PUBLIC_MEMBER表示Java对象中所有的public访问权限的成员变量和通过getter/setter方式访问的成员变量,该值为默认值

  1. XmlAccessType.NONE表示Java对象的所有属性都不映射为XML的元素

  • @XmlAccessorOrder

控制JAXB绑定类中属性和字段的排序,有两个属性,AccessorOrder.ALPHABETICAL——对生成的XML元素按字母书序排序,XmlAccessOrder.UNDEFINED——不排序,默认为该值;


import lombok.Data;

import javax.xml.bind.annotation.*;

/**
 * @描述: 测试类
 * @Date: 2023/3/8 13:50
 * @Description: // PC002
 * @Author: Duys
 **/
@Data
@XmlAccessorOrder(value = XmlAccessOrder.ALPHABETICAL)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "test")
public class TestVo {

    private String age;
    private String sex;
    private String birthday;
    private String value;


}
// 排序 
xml >>>
<test>
    <age>50岁</age>
    <birthday>2002-01-01</birthday>
    <sex>男</sex>
    <value>11</value>
</test> 
  • @XmlJavaTypeAdapter

自定义适配器(即扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),解决日期(Date),数字(Number)格式化问题;



import javax.xml.bind.annotation.adapters.XmlAdapter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @描述:
 * @Date: 2023/3/8 15:34
 * @Description: // PC002
 * @Author: Duys
 **/
public class MyAdapter extends XmlAdapter<String, Date> {

    static final String STANDARM_DATE_FORMAT = "yyyy-MM-dd";

    @Override
    public Date unmarshal(String v) throws Exception {
        if (v == null) {
            return null;
        }

        DateFormat format = new SimpleDateFormat(STANDARM_DATE_FORMAT);
        return format.parse(v);
    }

    @Override
    public String marshal(Date v) throws Exception {
        DateFormat format = new SimpleDateFormat(STANDARM_DATE_FORMAT);
        return format.format(v);
    }

}


import com.jfsoft.interfaces.entity.MyAdapter;
import lombok.Data;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.io.Serializable;
import java.util.Date;

/**
 * @描述: 测试类
 * @Date: 2023/3/8 13:50
 * @Description: // PC002
 * @Author: Duys
 **/
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "test")
public class TestVo implements Serializable {

    @XmlJavaTypeAdapter(MyAdapter.class)
    private Date createDate;
}


import com.jfsoft.interfaces.entity.his.vo.TestVo;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Date;

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class LisTest {

    @Test
    public void test0002() {

        TestVo vo = new TestVo();
        vo.setCreateDate(new Date());
        String xml = JaxbUtil.convertToXmlIgnoreXmlHead(vo, "utf-8");
        log.info("xml >>> {}", xml);
    }

}
// 输出
xml >>> 
<test>
    <createDate>2023-03-09</createDate>
</test>
  • @XmlElementWrapper

对于数组或集合(即包含多个元素的成员变量),生成一个包装该数组或集合的XML元素(称为包装器),该注解只能用在集合上;

 
import lombok.Data; 

/**
 * 申请单实体类
 */
@Data
public class RisOrdersVo {
 

    /**
     * 受检者姓名
     */
    private String name;
    
    /**
     *     申请单号
     */
    private String applyNo;

}


import com.jfsoft.interfaces.core.entity.vo.RisOrdersVo;
import com.jfsoft.interfaces.entity.MyAdapter;
import lombok.Data;

import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.io.Serializable;
import java.util.Date;
import java.util.List;

/**
 * @描述: 测试类
 * @Date: 2023/3/8 13:50
 * @Description: // PC002
 * @Author: Duys
 **/
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "test")
public class TestVo implements Serializable {

    @XmlJavaTypeAdapter(MyAdapter.class)
    private Date createDate;

    @XmlElementWrapper(name = "orders")
    @XmlElement(name = "order")
    private List<RisOrdersVo> ordersVoList;

}

import com.jfsoft.interfaces.core.entity.vo.RisOrdersVo;
import com.jfsoft.interfaces.entity.his.vo.TestVo;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class LisTest {

    @Test
    public void test0002() {

        RisOrdersVo risOrdersVo = new RisOrdersVo();
        risOrdersVo.setName("张三");
        risOrdersVo.setApplyNo("100001");
        List<RisOrdersVo> list = new ArrayList<>();
        list.add(risOrdersVo);
        TestVo vo = new TestVo();
        vo.setCreateDate(new Date());
        vo.setOrdersVoList(list);
        String xml = JaxbUtil.convertToXmlIgnoreXmlHead(vo, "utf-8");
        log.info("xml >>> {}", xml);
    }

}

// 输出
xml >>> 
<test>
    <createDate>2023-03-09</createDate>
    <orders>
        <order>
            <applyNo>100001</applyNo>
            <name>张三</name>
        </order>
    </orders>
</test>
  • @XmlTransient

用于标示在由Java对象映射XML时,忽略此属性,在生成的XML文件中将不出现此元素。该注解与所有其他JAXB注释相互排斥,也就是说与其他注释连用就会报错。



import lombok.Data;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import java.io.Serializable;

/**
 * @描述: 测试类
 * @Date: 2023/3/8 13:50
 * @Description: // PC002
 * @Author: Duys
 **/
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "test")
public class TestVo implements Serializable {


    private String t1;

    @XmlTransient
    private String t2;

    @XmlTransient
    private String t3;


}

import com.jfsoft.interfaces.entity.his.vo.TestVo;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class LisTest {

    @Test
    public void test0002() {

        TestVo vo = new TestVo();
        vo.setT1("1");
        vo.setT2("2");
        vo.setT3("3");
        String xml = JaxbUtil.convertToXmlIgnoreXmlHead(vo, "utf-8");
        log.info("xml >>> {}", xml);
    }

}

// 输出
xml >>> 
<test>
    <t1>1</t1>
</test>

@XmlAccessorType 注解中如果属性值为XmlAccessType.FIELD,则表示通过成员变量来映射,set/get方法上的映射注解就是多余的,所以如果此时set/get方法上再标注元素或者属性映射注解,将抛属性重复性异常;

属性值为XmlAccessType.NONE不映射为XML元素的前提是Java字段或set/get方法上都没有映射注解

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
注:下文中的 *** 代表文件名中的组件名称。 # 包含: 中文-英文对照文档:【***-javadoc-API文档-中文(简体)-英语-对照版.zip】 jar包下载地址:【***.jar下载地址(官方地址+国内镜像地址).txt】 Maven依赖:【***.jar Maven依赖信息(可用于项目pom.xml).txt】 Gradle依赖:【***.jar Gradle依赖信息(可用于项目build.gradle).txt】 源代码下载地址:【***-sources.jar下载地址(官方地址+国内镜像地址).txt】 # 本文件关键字: 中文-英文对照文档,中英对照文档,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-javadoc-API文档-中文(简体)版.zip】,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·本文档为双语同时展示,一行原文、一行译文,可逐行对照,避免了原文/译文来回切换的麻烦; ·有原文可参照,不再担心翻译偏差误导; ·边学技术、边学英语。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件;

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值