关于使用JAXBContext解析Xml的问题

因为业务需要,传过来的是Xml报文,需要解析成JavaBean来进行详细操作
之前是用的将Xml报文转成Element节点递归遍历成一个map来操作使用,这样真的是太复杂冗余了,最终使用JAXBContenx工具来进行解析操作,更简单便捷
首先就是将报文解析成Xml
先导入所需要的的Maven依赖

 		<dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0-b170201.1204</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/javax.activation/activation -->
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime -->
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.0-b170127.1453</version>
        </dependency>

主要还是用的Xml.bind这个包
然后就是代码:解析Xml为Javabean
被解析的对象需要添加@XmlRootElement注解

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.charset.Charset;
    /
    **
     * xml 解析成bean
     * @param xmlString
     * @param clazz
     * @param <T>
     * @return
     */
    public static final <T> T xml2bean(String xmlString, Class<T> clazz) {
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            return (T) unmarshaller.unmarshal(new StringReader(xmlString));
        } catch (JAXBException je) {
            logger.error("解析xml失败,失败的bean是: {}", clazz);
            logger.error("解析失败的xml是: {}", xmlString);
            throw new UnsupportedOperationException(je);
        }
    }

bean转成Xml


    public static final String bean2xml(Object object, Charset charset) {
        String XML_DECLARATION_UTF8 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
        String XML_DECLARATION_GBK = "<?xml version=\"1.0\" encoding=\"GBK\"?>";
        String result = "";
        JAXBContext context;
        try {
            context = JAXBContext.newInstance(object.getClass());
            Marshaller m = context.createMarshaller();
            m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
            m.setProperty(Marshaller.JAXB_ENCODING, charset.name());
            StringWriter writer = new StringWriter();
            m.marshal(object, writer);
            result = writer.toString();
            result = (charset.name().equalsIgnoreCase("GBK") ? XML_DECLARATION_GBK : XML_DECLARATION_UTF8) + result;
            return result;
        } catch (JAXBException je) {
            logger.info("转换失败,失败的bean是: {}", object.toString());
            logger.info("转换失败的字符集是: {}", charset);
            throw new UnsupportedOperationException(je);
        }
    }

测试

    @RequestMapping("Xml")
    public String Xml(@RequestBody String xmlString){
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(XmlFile.class);
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            XmlFile xmlFile = (XmlFile)unmarshaller.unmarshal(new StringReader(xmlString));
            System.out.println(xmlFile.getOrder().getAllPrice());
        } catch (JAXBException je) {
            throw new UnsupportedOperationException(je);
        } 
        return null;
    }

实体类的问题很关键,在根节点中也就是主类需要加上@XmlRootElement并指定他的name也就是Xml报文中的根节点,在基本类型也就是没有子节点的属性名上加上@XmlAttribute注解,如果Xml报文中有下划线的话,可能赋值不进来,得指定他的name对应一下;在引用数据属性上加上@XmlElment注解,同样可以指定名字绑定,


以上就是Xml转JavaBean的操作
因为业务只用到了Xml转JavaBean而没有用到JavaBean转Xml所以,在这里只提一嘴,下次用的时候在补上


@Test  
public void testJava2Xml(){  
    try {  
        JAXBContext jc = JAXBContext.newInstance(Man.class);  
        Marshaller ms = jc.createMarshaller();  
        Man man = new Man("man",100);  
        ms.marshal(man, System.out);  
    } catch (JAXBException e) {  
        e.printStackTrace();  
    }  
}  

出现具有两个相同属性的报错时,可能是因为解析类上没有加@XmlAccessorType(XmlAccessType.FIELD)这个注解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值