天天看点

java实体类解析成xml格式的字符串1.背景2.效果预览

1.背景

因工作需要生成xml格式的字符串,传到消息队列与其他服务通讯。如果自己手动string.append则非常繁琐且不可通用,故写了个工具类,将一个实体类解析成xml字符串。

2.效果预览

目标xml格式

<msg>
    <rvHeader>
        <source>
            <application>MES</application>
            <msgBus>Tibrv</msgBus>
            <domain></domain>
            <address></address>
        </source>
        <destination>
            <application>EAP</application>
            <msgBus>Tibrv</msgBus>
            <domain></domain>
            <address>.EAP.></address>
        </destination>
    </rvHeader>
    <msgBody>
        <retMessage/>
        <action>1</action>
        <retCode>1</retCode>
    </msgBody>
</msg>

           

源java代码

@Data
@XmlTagName("msg")
public class Msg {

    private RvHeader rvHeader;

    private MsgHeader msgHeader;

    private MsgBody msgBody;

    public static Msg newInstance() {
        Msg msg = new Msg();
        msg.rvHeader = new RvHeader();
        msg.msgHeader = new MsgHeader();
        return msg;
    }
    public static Msg newInstance(MsgBody msgBody) {
        Msg msg = new Msg();
        msg.rvHeader = new RvHeader();
        msg.msgHeader = new MsgHeader();
        msg.msgBody = msgBody;
        return msg;
    }
}


@Data
@XmlTagName("rvHeader")
public class RvHeader {

    private Source source;

    private Destination destination;

    public RvHeader() {
        this.source = new Source();
        this.destination = new Destination();
    }

    public static RvHeader newInstance() {
        return new RvHeader();
    }
}


@Data
@XmlTagName("source")
public class Source {

    private String application;

    private String msgBus;

    private String domain;

    private String address;
}

@Data
@XmlTagName("destination")
public class Destination {
    private String application;

    private String msgBus;

    private String domain;

    private String address;
}

@Data
@XmlTagName("msgBody")
public class EAPReqDestinationForZBRequestDto implements MsgBody {
    private String userId;

    private String eqpId;

    private String lotId;

    private String pausePoint;
}

public interface MsgBody {
}

@Documented
@Target({ElementType.TYPE, ElementType.FIELD})
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface XmlTagName {
    String value();
}
           

工具类代码

Msg msg = new Msg();
// todo 设置msg里面各个类的成员变量属性。。。代码省略

// 打印xml格式的字符串
System.out.println(XmlUtils.objectFormat2Xml(msg));
           

XmlUtils

xml的具体的name我设计通过注解来获取,如果没有写注解,则取成员变量的名称。需要用到反射机制,要引用部分反射的类

import java.lang.reflect.Field;

public static String objectFormat2Xml(Object object) {
        StringBuilder builder = new StringBuilder();
        int spaceCount = 0;
        try {
            XmlUtils.elementFormat(object, builder, spaceCount);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return builder.toString();
    }
public static void elementFormat(Object object, StringBuilder builder, int spaceCount) throws Exception {


        Class<?> classType = object.getClass();
        String objectName = classType.getAnnotation(XmlTagName.class).value(); //获取对象的属性名称
        builder.append(getSpaceStringByCount(spaceCount) + "<" + objectName + ">\n");
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            //获取f对象对应类中的所有属性域
            field.setAccessible(true);

            Class<?> type = field.getType();
            XmlTagName annotation = field.getAnnotation(XmlTagName.class);
            String name = annotation == null ? field.getName() : annotation.value(); //获取对象的属性名称
            Object value = field.get(object);//获取对象的属性值


            if (String.class.isAssignableFrom(type)) { // 如果是string 则直接拼接值
                if (value == null) {
                    builder.append(getSpaceStringByCount(spaceCount + 4) + "<" + name + "/>\n");
                    continue;
                }
                builder.append(getSpaceStringByCount(spaceCount + 4) + "<" + name + ">").append(value).append("</" + name + ">\n");
                continue;
            }

            if (List.class.isAssignableFrom(type)) { // 如果是List
                List<Object> list = (List<Object>) value;
                if (list.isEmpty()) {
                    builder.append(getSpaceStringByCount(spaceCount + 4) + "<" + name + "/>\n");
                    continue;
                }

                builder.append(getSpaceStringByCount(spaceCount + 4) + "<" + name + ">\n");
                for (Object o : list) {
                    XmlUtils.elementFormat(o, builder, spaceCount + 8);
                }
                builder.append(getSpaceStringByCount(spaceCount + 4) + "</" + name + ">\n");
            } else { // object对象类型
                XmlUtils.elementFormat(value, builder, spaceCount + 4);
            }

        }
        builder.append(getSpaceStringByCount(spaceCount) + "</" + objectName + ">\n");
    }

public static String getSpaceStringByCount(int count) {
        StringBuilder builder = new StringBuilder();
        while (count-- > 0) {
            builder.append(" ");
        }
        return builder.toString();
    }