JAXB解析xml

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;
        }
    }

	/**
     * 对象转换成xmlString
     */
    public static String convertToXmlStr(Object obj) throws Exception {
        //创建输出流
        StringWriter sw = new StringWriter();
        sw.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\n");
        JAXBContext context = JAXBContext.newInstance(obj.getClass());
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
        marshaller.marshal(obj, sw);
        return sw.toString();
    }

    /**
     * 对象转换成xmlString,
     * 会带上 xsi:noNamespaceSchemaLocation="request.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     */
    public static String convertToXmlStrWithXsi(Object obj, String schemaLocation) throws Exception {
        StringWriter sw = new StringWriter();
        sw.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\n");
        JAXBContext context = JAXBContext.newInstance(obj.getClass());
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
        marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, schemaLocation);
        marshaller.marshal(obj, sw);
        return sw.toString();
    }
}

对象加上注解即可,注意根节点要单独标注@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”))

都需要指定编码方式。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值