版权声明:本文为博主原创文章,转载请注明出处。 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><9;9>1&-<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>->78--<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>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”))
都需要指定编码方式。