策略枚举的用法七:实体转换

160 阅读2分钟

1.场景

在对接外部系统时,有时候会提供一个Object的对象,这个对象会根据不同的类型传递不同的内容。例如下面的例子:

下图中的data根据eventType不同,信息也不一样。 image.png 这时,我们就需要根据eventType映射不同的类型。

1.枚举

import cn.hutool.json.JSONUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.stream.Stream;

/**
 * <p> 事件类型 </p>
 *
 * @author hongtool
 * @date 2023/3/1
 */
@Getter
@AllArgsConstructor
public enum EventTypeEnum {
    DEFAULT("") {
        @Override
        public <E extends EventBaseData> E changeData(Object data) {
            return null;
        }
    },
    S1("1") {
        @Override
        public EventData1 changeData(Object data) {
            return JSONUtil.toBean(JSONUtil.toJsonStr(data), EventData1.class);
        }
    },
    S2("2") {
        @Override
        public EventData2 changeData(Object data) {
            return JSONUtil.toBean(JSONUtil.toJsonStr(data), EventData2.class);
        }
    },
    
    ;
    
    public abstract <E extends EventBaseData>  E changeData(Object data);
    
    private final String code;
    
    public static EventTypeEnum indexOf(String code) {
        return Stream.of(values()).filter(e -> e.getCode().equals(code)).findFirst().orElse(DEFAULT);
    }
    
}

2. 实体模型(简化一下)

最外层的实体对象

import lombok.Data;

/**
 * <p> 对象模型 </p>
 *
 * @author hongtool
 * @date 2023/3/1
 */
@Data
public class EventsBO<E> {
    
    private String eventId;
    /** 事件类型 */
    private String eventType;
    /** 接收对象 */
    private Object data;
    /** 真实解析后的对象 */
    private E e;
    
}

data 模型这里列举了两个(抽取一个抽象基类)

import lombok.Data;

/**
 * <p> TODO </p>
 *
 * @author hongtool
 * @date 2023/3/1
 */
@Data
public abstract class EventBaseData {

}
import lombok.Data;

/**
 * <p> eventType = 1 时的实体模型 </p>
 *
 * @author hongtool
 * @date 2023/3/1
 */
@Data
public class EventData1 extends EventBaseData  {
    
    private String name1;
    private EventData11 data11;
    
}
import lombok.Data;

/**
 * <p> TODO </p>
 *
 * @author hongtool
 * @date 2023/3/1
 */
@Data
public class EventData11 {
    
    private String name11;
    
    private String type11;
    
}
/**
 * <p> eventType = 2 时的实体模型 </p>
 *
 * @author hongtool
 * @date 2023/3/1
 */
@Data
public class EventData2 extends EventBaseData  {
    
    private String name2;
    
}

3. 测试

import cn.hutool.json.JSONUtil;

/**
 * <p> 测试 </p>
 *
 * @author hongtool
 * @date 2023/3/1
 */
public class EventTest {
    
    public static void main(String[] args) {
        EventsBO bo1 = new EventsBO();
        bo1.setEventId("1");
        bo1.setEventType("1");
        EventData1 data1 = new EventData1();
        data1.setName1("name1");
        EventData11 data11 = new EventData11();
        data11.setName11("name11");
        data11.setType11("type11");
        data1.setData11(data11);
        bo1.setData(data1);
        String s1 = JSONUtil.toJsonStr(bo1);
        System.out.println("bo1---->" + s1);
        EventsBO bo2 = new EventsBO();
        bo2.setEventId("2");
        bo2.setEventType("2");
        EventData2 data2 = new EventData2();
        data2.setName2("name2");
        bo2.setData(data2);
        String s2 = JSONUtil.toJsonStr(bo2);
        System.out.println("bo2---->" + s2);
        
        // 开始解析
        EventsBO<EventData1> b1 = JSONUtil.toBean(s1, EventsBO.class);
        b1.setE(EventTypeEnum.indexOf(b1.getEventType()).changeData(b1.getData()));
        System.out.println(b1);
    
        // 开始解析
        EventsBO<EventData2> b2 = JSONUtil.toBean(s2, EventsBO.class);
        b2.setE(EventTypeEnum.indexOf(b2.getEventType()).changeData(b2.getData()));
        System.out.println(b2);
    }
    
}

4. 输出

从结果中可以看出,两个对象有转换成功。

image.png

总结

记录记录,没啥好总结的