Java必备技能之 Xml解析与生成,再也不怕Xml与Bean的转化了

1 背景

声明:本文不涉及XML节点操作,仅仅适用于Bean与XML的转化过程。
当第三方接口传输格式为XML格式,拼接XML格式参数以及解析XML响应结果是无法逃避的问题。类似这种场景,不需要操作XML的DOM节点,只要会XML与DOM转化即可。

2 XML解析与生成

2.1 工具类

由于不需要操作XML节点,所以不需要引入类似dom4j之类的解析框架,仅仅使用JDK 1.8 的API即可。为了更好的操作,需要编写合适的工具类。下面给出代码,需要的请拿走。

package xyz.yq56.sdk.util;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;

/**
 * @author yiqiang
 */
@SuppressWarnings("unused")
public class JaXmlBeanUtil {

    public static String convertToXml(Object obj) {
        return convertToXml(obj, "UTF-8");
    }

    /**
     * JavaBean转换成xml
     */
    public static String convertToXml(Object obj, String encoding) {
        String result = null;
        try {
            JAXBContext context = JAXBContext.newInstance(obj.getClass());
            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
            StringWriter writer = new StringWriter();
            marshaller.marshal(obj, writer);
            result = writer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * xml转换成JavaBean
     */
    @SuppressWarnings("unchecked")
    public static <T> T convertToJavaBean(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 e) {
            e.printStackTrace();
        }
        return t;
    }

}

2.2 相关注解

XML与Bean的转化依赖于注解,下面给出常用注解

  • @XmlRootElement(name = “response”)
    该注解表明这是XML的根节点,必须存在。XML的解析与生成会从标有此注解的地方开始,而中间对象标注或不标注不影响结果。
  • @XmlAccessorType(XmlAccessType.FIELD)
    常与@XmlRootElement联用,表明所有属性均会被解析。如果设置为XmlAccessType.PROPERTY,则只会解析拥有get和set方法的属性。
  • @XmlElementWrapper
    当使用了集合时,需要标注此注解。会在外层包裹一个集合标签,默认使用属性名称。但这样会出现一个问题,集合标签和元素标签都使用的同一个属性名称。为解决这个问题,一般还需要添加@XmlElement改变元素的名称。
  • @XmlElement
    这个注解可以改变属性对应的XML节点名称,类似@JsonProperty
  • @XmlJavaTypeAdaptor
    标注在接口 属性上,为接口指定具体的实现类。当属性为接口时,必须指定该注解。

2.3 使用步骤

2.3.1 定义XML对应的Bean

定义三个Bean,具体注解含义见2.2

@Getter
@Setter
@XmlRootElement(name = "response")
@XmlAccessorType(value = XmlAccessType.FIELD)
public class ResponseElement {
    private int id;
    private String name;

    @XmlElementWrapper
    @XmlElement(name = "user")
    private List<User> userList;

}

@Getter
@Setter
public class User {
    private int id;
    private String username;
    private String password;
}

//测试继承
@Getter
@Setter
@XmlRootElement
public class ResponseExt extends ResponseElement{
    private String field1;
}

2.3.2 使用工具类进行解析

  • 生成XML:String xml=JaXmlBeanUtil.convertToXml(requestElement)
  • 解析XML:ResponseExt responseExt=JaXmlBeanUtil.convertToJavaBean(xml, ResponseExt.class);

3 效果展示

3.1 测试代码

/**
 * @author Yi Qiang
 * @version 1.0.0
 * @date 2020/10/12 19:05
 */
@Slf4j
public class XmlTest {
    private static ObjectMapper mapper=new ObjectMapper();

    public void marshal() {
        ResponseElement response=new ResponseElement();
        response.setId(1);
        response.setName("yq");

        User user=new User();
        user.setId(1);
        user.setUsername("test");
        user.setPassword("123456");

        User user2=new User();
        user2.setId(2);
        user2.setUsername("test2");
        user2.setPassword("1234562");

        List<User> list=new ArrayList<User>();
        list.add(user2);
        list.add(user);
        response.setUserList(list);
        log.info(JaXmlBeanUtil.convertToXml(response));


        ResponseExt ext=new ResponseExt();
        ext.setField1("field1");
        ext.setUserList(list);
        ext.setId(3);
        ext.setName("test3");

        log.info(JaXmlBeanUtil.convertToXml(ext));
    }

    public void unmarshal() throws JsonProcessingException {


        String xml="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
                "<responseExt>\n" +
                "    <id>3</id>\n" +
                "    <name>test3</name>\n" +
                "    <userList>\n" +
                "        <user>\n" +
                "            <id>2</id>\n" +
                "            <password>1234562</password>\n" +
                "            <username>test2</username>\n" +
                "        </user>\n" +
                "        <user>\n" +
                "            <id>1</id>\n" +
                "            <password>123456</password>\n" +
                "            <username>test</username>\n" +
                "        </user>\n" +
                "    </userList>\n" +
                "    <field1>field1</field1>\n" +
                "</responseExt>";

        ResponseElement responseElement = JaXmlBeanUtil.convertToJavaBean(xml, ResponseExt.class);
        log.info(mapper.writeValueAsString(responseElement));
    }

    public static void main(String[] args) throws JsonProcessingException {
        XmlTest test=new XmlTest();
        test.marshal();
        log.info("");
        test.unmarshal();
    }


}

3.2 运行结果

14:08:04.936 [main] INFO xyz.yq56.test.XmlTest - <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
    <id>1</id>
    <name>yq</name>
    <userList>
        <user>
            <id>2</id>
            <password>1234562</password>
            <username>test2</username>
        </user>
        <user>
            <id>1</id>
            <password>123456</password>
            <username>test</username>
        </user>
    </userList>
</response>

14:08:05.018 [main] INFO xyz.yq56.test.XmlTest - <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<responseExt>
    <id>3</id>
    <name>test3</name>
    <userList>
        <user>
            <id>2</id>
            <password>1234562</password>
            <username>test2</username>
        </user>
        <user>
            <id>1</id>
            <password>123456</password>
            <username>test</username>
        </user>
    </userList>
    <field1>field1</field1>
</responseExt>

14:08:05.018 [main] INFO xyz.yq56.test.XmlTest - 
14:08:05.274 [main] INFO xyz.yq56.test.XmlTest - {"id":3,"name":"test3","userList":[{"id":2,"username":"test2","password":"1234562"},{"id":1,"username":"test","password":"123456"}],"field1":"field1"}

4 结语

对于第三方接口对接,难免遇到XML传输。如果本文对你有所帮助,请给我点个赞!!与君共勉

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值