xml与实体之间的转换

在对接一些第三方接口的时候往往需要涉及到一些对xml文件的处理,小编今天主要总结一下JavaBean与xml文件之间互相转换的探索与实例

使用JAXB技术实现xml与实体之间的转换

1. 是什么:

JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到 XML实例文档。

2. 常用注解
@XmlRootElement:用于类级别的注解,对应xml的跟元素。通过name属性定义这个根节点的名称。
@XmlAccessorType:定义映射这个类中的何种类型都需要映射到xml(控制字段或属性的序列化)

XmlAccessorType的几种类型说明:
1. XmlAccessType.PUBLIC_MEMBER(默认):java对象中所有的public访问权限的成员变量和通过getter/setter方式访问的成员变量。
2. XmlAccessType.FIELD: java对象中的所有成员变量
3. XmlAccessType.PROPERTY:java对象中所有通过getter/setter方式访问的成员变量。(除非用@XmlTransient注释)
4. XmlAccessType.NONE: java对象的所有属性都不映射为xml的元素。

@XmlAttribute:用于把java对象的属性映射为xml的属性,并可通过name属性为生成的xml属性指定别名。
@XmlElement:指定一个字段或get/set方法映射到xml的节点。通过name属性定义这个根节点的名称。
@XmlElementWrapper,为数组或集合定义一个父节点。通过name属性定义这个父节点的名称。
@XmlTransient:它会为它的target阻止绑定操作,这个target可以是一个class或者一个field或者一个method。如果你遇到了从public field导致的名字冲突(拿foo来说,getFoo和setFoo),那么使用这个注解将会是很有用的
@XmlJavaTypeAdapter:使用定制的适配器(即扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),以序列化Java类为XML(可以应用于对

3.应用实例

  1. 相关工具类:
/**
     * beanToXml工具类
     * @param obj 待转化实体
     * @param load 带有xml元素的实体类
     * @param encoding 编码格式
     * @return
     * @throws JAXBException
     */
public static String beanToXml(Object obj, Class<?> load, String encoding) throws JAXBException {
        if (encoding == null || encoding.isEmpty()) {
            encoding = "UTF-8";
        }
        JAXBContext context = JAXBContext.newInstance(load);
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);//格式化
        marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);//设置编码
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);

        //防止
        marshaller.setProperty(CharacterEscapeHandler.class.getName(),
                (CharacterEscapeHandler)(chars, start, length, isAttVal, writer) -> writer.write(chars, start, length));

        StringWriter writer = new StringWriter();

        //添加表头
        writer.write(" + encoding + "\'?>\n");
        marshaller.marshal(obj, writer);
        return writer.toString();
    }
/**
     * xml转bean工具类
     * @param xml string类型的xml串
     * @param  目标实体类
     * @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 ex) {
            log.error(ex.getMessage(), ex);
        }
        return t;
    }
/**
 * 扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),以序列化Java类为XML
 * 此处目的在于对的数据进行包装和解析
 */
public class CDataAdapter extends XmlAdapter<String, String>
{
    @Override
    public String marshal (String v) throws Exception
    {
        if(v==null||v.isEmpty()){
            return v;
        }
        return new StringBuilder(").append(v).append("]]>").toString();
    }
    @Override
    public String unmarshal (String v) throws Exception
    {
        if ("".equals (v))
        {
            return "";
        }
        String v1 = null;
        String v2 = null;
        String subStart = ";
        int a = v.indexOf (subStart);
        if (a >= 0)
        {
            v1 = v.substring (subStart.length (), v.length ());
        }
        else
        {
            return v;
        }
        String subEnd = "]]>";
        int b = v1.indexOf (subEnd);
        if (b >= 0)
        {
            v2 = v1.substring (0, b);
        }
        return v2;
    }

}
  1. 相关实体定义:
@Data
@XmlRootElement(name="OrderList")
@XmlAccessorType(XmlAccessType.FIELD)
public class OrderDTO {

    @XmlElement(name="orderNumber")
    private String orderNo;

    @XmlElement(name="customerName")
    private String customerName;

    @XmlElementWrapper(name="items")
    @XmlElement(name="item")
    private List<OrderItemDTO> orderItemDTOList;
}

@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class OrderItemDTO {
    
    @XmlJavaTypeAdapter(CDataAdapter.class)
    @XmlElement(name="Title")
    private String productName;
    
    @XmlElement(name = "Number")
    private Integer productNumber;
}
  1. 以Test的形式展示一下执行效果
public class SerializeXmlTest {

    private OrderDTO orderDTO=new OrderDTO();
    private List<OrderItemDTO> orderItemDTOList=new ArrayList<>();
    @Before
    public void init(){
        orderDTO.setOrderNo("1231");
        orderDTO.setCustomerName("test");
        OrderItemDTO orderItemDTO=new OrderItemDTO();
        orderItemDTO.setProductName("spu1");
        orderItemDTO.setProductNumber(2);
        orderItemDTOList.add(orderItemDTO);
        orderDTO.setOrderItemDTOList(orderItemDTOList);
    }

    @Test
    public void xmlToBean() throws JAXBException {
        String xml=XMLUtils.beanToXml(orderDTO,OrderDTO.class,null);
        System.out.println("转xml:\n".concat(xml));
    }

    @Test
    public void beanToXml(){
        String xml="\n" +
                "\n" +
                "    1231\n" +
                "    test\n" +
                "    \n" +
                "        \n" +
                "            <![CDATA[spu1]]>\n" +
                "            2\n" +
                "        \n" +
                "    \n" +
                "";
        OrderDTO orderDTO=XMLUtils.converyToJavaBean(xml,OrderDTO.class);
        System.out.println("转实体:\n"+JSONUtils.toJSONString(orderDTO));
    }
}

4.结果展示:
xml与实体之间的转换_第1张图片

你可能感兴趣的:(★——计算机学习之旅——)