JAXB解析xml

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/u013041642/article/details/80009175

JAXB解析xml真是非常的方便,只需在对象上加上注解,标注对应xml文件的节点即可。很方便。下面是一个示例。

封装解析用到的代码,提供三个方法,一个是将字符串解析为对象,一个是读取一个xml文件解析,另一个是将输入流解析为对象。

package cn.com.servyou.hs.support.core.util;
import lombok.extern.slf4j.Slf4j;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

/**
 * @author susq
 * @since 2018-04-13-20:54
 */
@Slf4j
public class XmlUtils {

    @SuppressWarnings("unchecked")
    public static <T> T parseInputStream(Class<T> clazz, InputStream dataStream) throws JAXBException {
        try {
            JAXBContext jc = JAXBContext.newInstance(clazz);
            Unmarshaller u = jc.createUnmarshaller();
            return (T) u.unmarshal(dataStream);
        } catch (JAXBException e) {
             log.error(e.getMessage());
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    public static <T> T parseInputString(Class<T> clazz, String dataStr) throws JAXBException, UnsupportedEncodingException {
        try {
            JAXBContext jc = JAXBContext.newInstance(clazz);
            Unmarshaller u = jc.createUnmarshaller();
            return (T) u.unmarshal(new ByteArrayInputStream(dataStr.getBytes("UTF-8")));
        } catch (JAXBException e) {
            log.error(e.getMessage());
        }
        return null;
    }

  @SuppressWarnings("unchecked")
    public static <T> T parseFile(Class<T> clazz, String fileName) throws JAXBException {
        try {
            JAXBContext jc = JAXBContext.newInstance(clazz);
            Unmarshaller u = jc.createUnmarshaller();
            return (T) u.unmarshal(new File(fileName));
        } catch (JAXBException e) {
            log.error(e.getMessage());
            throw e;
        }
    }

}

对象加上注解即可,注意根节点要单独标注@XmlRootElement,其他节点都是@XmlElement 标注即可。

package com.susq.zipBase64;

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 java.math.BigDecimal;
import java.util.Date;

/**
 * @author susq
 * @since 2018-04-17-10:23
 */
@XmlRootElement(name = "fpmx")
@XmlAccessorType(XmlAccessType.FIELD)
public class UnAuthInvoiceDto {
    @XmlElement(name = "fpLb")
    private Integer fplb;
    @XmlElement(name = "fpdm")
    private String fpdm;
    @XmlElement(name = "fphm")
    private String fphm;
    @XmlElement(name = "kprq")
    private Date kprq;
    @XmlElement(name = "xfsbh")
    private String sfsbh;
    @XmlElement(name = "xfmc")
    private String xfmc;
    @XmlElement(name = "gfsbh")
    private String gfsbh;
    @XmlElement(name = "gfmc")
    private String gfmc;
    @XmlElement(name = "je")
    private BigDecimal je;
    @XmlElement(name = "se")
    private BigDecimal se;
    @XmlElement(name = "")
    private String skm;
    @XmlElement(name = "jqbh")
    private String jqbh;
    @XmlElement(name = "sklx")
    private Integer sklx;

    // getter setter toString 省略
}

测试

 public static void main(String[] args) throws JAXBException {
        String xml = "<fpmx>\n" +
                "      <fpLb>1</fpLb>\n" +
                "      <fpdm>120</fpdm>\n" +
                "      <fphm>07868</fphm>\n" +
                "      <kprq>2018-03-30 16:35:09.0</kprq>\n" +
                "      <xfsbh>91C</xfsbh>\n" +
                "      <xfmc>有限公司</xfmc>\n" +
                "      <gfsbh>91397067</gfsbh>\n" +
                "      <gfmc>有限公司</gfmc>\n" +
                "      <je>689513.07</je>\n" +
                "      <se>117217.23</se>\n" +
                "      <skm>&lt;9;9&gt;1&-&lt;215+4</skm>\n" +
                "      <jqbh>66152799</jqbh>\n" +
                "      <sklx>1</sklx>\n" +
                "    </fpmx>";

        UnAuthInvoiceDto dto = parseInputString(UnAuthInvoiceDto.class, xml);
        System.out.println(dto.toString());
    }

输出:

UnAuthInvoiceDto{fplb=1, fpdm='1230', fphm='078', kprq=null, sfsbh='9112011', xfmc=')有限公司', gfsbh='914401165602397067', gfmc='品有限公司', je=689513.07, se=117217.23, skm='<9-9804-89036+*4<67/1*0>2988<//375>9>1>*0+--247*357971593<*/6*->78--<215+4', jqbh='66199', sklx=1}

即使是复杂的嵌套对象,也可以解析。例如:根节点下面是个列表,创建对应结构的对象,一个上层对象包含了下层对象的列表。只需要将更节点移到对应位置即可。

@XmlRootElement(name = "fpmxs") 
@XmlAccessorType(XmlAccessType.FIELD)
public class UnAuthInvoiceResult {

    @XmlElement(name = "fpmx")
    private List<UnAuthInvoiceDto> unAuthInvoiceDtoList;

    // getter setter 省略
}

测试

public static void main(String[] args) throws JAXBException {
        String xml = "<fpmxs>\n" +
                "    <fpmx>\n" +
                "      <fpLb>1</fpLb>\n" +
                "      <fpdm>1130</fpdm>\n" +
                "      <fphm>0768</fphm>\n" +
                "      <kprq>2018-03-30 16:35:09.0</kprq>\n" +
                "      <xfsbh>91126325C</xfsbh>\n" +
                "      <xfmc>有限公司</xfmc>\n" +
                "      <gfsbh>91497067</gfsbh>\n" +
                "      <gfmc>制品有限公司</gfmc>\n" +
                "      <je>689513.07</je>\n" +
                "      <se>117217.23</se>\n" +
                "      <skm>-&gt;78--&lt;215+4</skm>\n" +
                "      <jqbh>661799</jqbh>\n" +
                "      <sklx>1</sklx>\n" +
                "    </fpmx>\n" +
                "    <fpmx>\n" +
                "      <fpLb>1</fpLb>\n" +
                "      <fpdm>2130</fpdm>\n" +
                "      <fphm>0183</fphm>\n" +
                "      <kprq>2018-03-14 00:00:00.0</kprq>\n" +
                "      <xfsbh>912199</xfsbh>\n" +
                "      <xfmc>限公司</xfmc>\n" +
                "      <gfsbh>967</gfsbh>\n" +
                "      <gfmc>限公司</gfmc>\n" +
                "      <je>22244.82</je>\n" +
                "      <se>3781.62</se>\n" +
                "      <skm>8-t;-4&g&gt;717+/67-</skm>\n" +
                "      <jqbh/>\n" +
                "      <sklx>1</sklx>\n" +
                "    </fpmx>" +
                "   </fpmxs>";

        UnAuthInvoiceResult dto = parseInputString(UnAuthInvoiceResult.class, xml);
        System.out.println(dto.toString());
    }

输出:

UnAuthInvoiceResult{unAuthInvoiceDtoList=[UnAuthInvoiceDto{fplb=1, fpdm='120130', fphm='0788', kprq=null, sfsbh='9116325C', xfmc='神有限公司', gfsbh='9197067', gfmc='品有限公司', je=689513.07, se=117217.23, skm='<9-9lt;*/6*-1;78--<215+4', jqbh='66199', sklx=1}, UnAuthInvoiceDto{fplb=1, fpdm='210010', fphm='013683', kprq=null, sfsbh='91', xfmc='限公司', gfsbh='92397067', gfmc='品有限公司', je=22244.82, se=3781.62, skm='8-/73*501-75>>-4-', jqbh='', sklx=1}]}

可能遇到的问题

MalformedByteSequenceException: 3 字节的 UTF-8 序列的字节 2 无效

MalformedByteSequenceException: 2 字节的 UTF-8 序列的字节 2 无效

中文乱码

这些都是编码方式的问题。通过byte[] 创建字符串,如 String s = new String(b, “UTF-8”),通过字符串.getByte()取得字节数组再创建输入流的时候,如:new ByteArrayInputStream(xml.getBytes(“UTF-8”))

都需要指定编码方式。

猜你喜欢

转载自blog.csdn.net/u013041642/article/details/80009175