java xml与实体之间的转换(附有XXE漏洞解决方案)

发布时间:2024年01月11日

📢博客主页:折戏花

📢欢迎点赞 👍 收藏 ?留言 📝 如有错误敬请指正!

📢本文由折戏花编写,首发于CSDN🙉

平时开发与第三方对接的时候往往会涉及到xml格式的处理,小编这里就记录一下用到的javaBean与xml之间的相互转换

利用JAXB技术实现xml与实体之间的相互转换

1、JAXB介绍

JAXB能够使用Jackson对JAXB注解的支持实现(jackson-module-jaxb-annotations),既方便生成XML,也方便生成JSON,这样一来可以更好的标志可以转换为JSON对象的JAVA类。JAXB允许JAVA人员将JAVA类映射为XML表示方式,常用的注解包括:@XmlRootElement,@XmlElement等等

2、注解

@XmlRootElement注解用于指定类的XML根元素的名称。通过在类上添加该注解,可以将该类映射为XML文档的根元素。使用该注解可以指定根元素的名称,并且可以与其他注解(如@XmlType、@XmlAccessorType、@XmlAccessorOrder等)一起使用

@XmlRootElement(name = "MyRootElement")
public class MyClass {
    // 类的成员变量和方法
}

@XmlAccessorType用于指定类中属性的访问方式。它有以下几个选项:

XmlAccessType.FIELD:表示使用字段访问方式,即直接访问类中的字段。这是默认的访问方式。

XmlAccessType.PROPERTY:表示使用属性访问方式,即通过getter和setter方法访问类中的属性。

XmlAccessType.PUBLIC_MEMBER:表示使用公共成员访问方式,即通过公共字段和公共getter和setter方法访问类中的属性。

XmlAccessType.NONE:表示不使用任何访问方式,即不访问类中的属性。

@XmlAccessorType(XmlAccessType.FIELD)
public class MyClass {
}

@XmlAttribute将JavaBean属性映射到XML属性,通过使用name属性,可以指定该元素在生成的XML中的属性名称

@XmlRootElement(name = "OBJECT")
@XmlAccessorType(XmlAccessType.FIELD)
public class MyClass{
    @XmlAttribute(name = "TYPE")
    private String type;
}

@XmlElement用于在使用JAXB或其他XML绑定技术时,控制Java类与XML数据之间的映射关系,通过使用name属性,可以指定该元素在生成的XML中的名称

@XmlRootElement(name = "Response")
@XmlAccessorType(XmlAccessType.FIELD)
public class MyClass{
    @XmlElement(name = "TYPE")
     private String type;;

}

3、使用示例

工具类

import lombok.extern.slf4j.Slf4j;

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

@Slf4j
public class XmlUtil {

    public static String beanToXml(Object obj, Class<?> load) {
        String xmlStr = null;
        try {
            JAXBContext context = JAXBContext.newInstance(load);
            Marshaller marshaller = context.createMarshaller();
            // 去掉生成xml的默认报文头
            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
            StringWriter writer = new StringWriter();
            marshaller.marshal(obj, writer);
            xmlStr = writer.toString();
        } catch (JAXBException e) {
            log.error("实体转为xml时出错!", e);
        }
        return xmlStr;
    }

    public static Object xmlToBean(String str, Class<?> load) {
        Object object = null;
        try {
            JAXBContext context = JAXBContext.newInstance(load);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            object = unmarshaller.unmarshal(new StringReader(str));
        } catch (JAXBException e) {
            log.error("xml转换到实体时出错,xml信息={},报错信息={}!", str, e);
        }
        return object;
    }
}

实体定义及执行结果展示
@XmlAttribute

@Data
@XmlRootElement(name = "OBJECT")
@XmlAccessorType(XmlAccessType.FIELD)
public class Test {

    @XmlAttribute(name = "ID")
    private String id;
    
    @XmlAttribute(name = "TYPE")
    private String type;
    
}
  public static void main(String[] args) {
        Test test = new Test();
        test.setId("1");
        test.setType("类型");
        String xml = XmlUtil.beanToXml(test,Test.class);
        System.out.println(xml);
        Test newTest = (Test) XmlUtil.xmlToBean(xml,Test.class);
        System.out.println(newTest);
    }

在这里插入图片描述

@XmlElement

@Data
@XmlRootElement(name = "OBJECT")
@XmlAccessorType(XmlAccessType.FIELD)
public class Test {

    @XmlElement(name = "ID")
    private String id;

    @XmlElement(name = "TYPE")
    private String type;

}

public static void main(String[] args) {
        Test test = new Test();
        test.setId("1");
        test.setType("类型");
        String xml = XmlUtil.beanToXml(test,Test.class);
        System.out.println(xml);
        Test newTest = (Test) XmlUtil.xmlToBean(xml,Test.class);
        System.out.println(newTest);
    }

在这里插入图片描述

4、外部实体注入漏洞解决

XML外部实体注入漏洞,即XXE(XML External Entity),此漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击等危害

将XMLInputFactory.SUPPORT_DTD 和XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES设置为false,禁止DTD


    public static Object xmlToBean(String str, Class<?> load) {
        Object object = null;
        try {
            JAXBContext context = JAXBContext.newInstance(load);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
            //禁止DTD,防止XXE漏洞
            xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
            xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
            final XMLStreamReader xmlStreamReader = xmlInputFactory
                    .createXMLStreamReader(new StringReader(str));
            object = unmarshaller.unmarshal(xmlStreamReader);
        } catch (JAXBException | XMLStreamException e) {
            log.error("xml转换到实体时出错,xml信息={},报错信息={}!", str, e);
        }
        return object;
    }
文章来源:https://blog.csdn.net/lqr666/article/details/135479382
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。