jackson抽象类多实现序列化方法

自定义反序列化方法

方法一,枚举保存类名与实现类的关系

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import lab.workflow.constant.WorkFlowType;
import lab.workflow.dto.node.WorkflowNode;
import lombok.extern.slf4j.Slf4j;
import org.reflections.Reflections;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Set;
import java.util.TimeZone;

@Configuration
@Slf4j
public class JsonConfiguration {
    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(ObjectMapper objectMapper){
        objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
        objectMapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);
        SimpleModule module = new SimpleModule();
        module.addDeserializer(WorkflowNode.class, new WorkflowNodeDeserializer());
        objectMapper.registerModule(module);
        MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
        mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
        return mappingJackson2HttpMessageConverter;
    }

    public static class WorkflowNodeDeserializer extends JsonDeserializer<WorkflowNode> {

        Reflections reflections =new Reflections("lab.workflow.dto.node.*");

        Set<Class<? extends WorkflowNode>> nodeClass = reflections.getSubTypesOf(WorkflowNode.class);

        static ObjectMapper objectMapper = new ObjectMapper();

        static {

            objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
            objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
            objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
            objectMapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);
            SimpleModule module = new SimpleModule();
            module.addDeserializer(WorkflowNode.class, new WorkflowNodeDeserializer());
            objectMapper.registerModule(module);
        }

        public WorkflowNodeDeserializer() {
        }

        @Override
        public WorkflowNode deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
            try {
                JsonNode treeNode = p.getCodec().readTree(p);
                String type = treeNode.get("type").asText();
                log.info(nodeClass.toString());
                if(!ObjectUtils.isEmpty(type)){
                    WorkFlowType workFlowType = WorkFlowType.getByName(type);
                    if(workFlowType != null){
                        Class<? extends WorkflowNode> tClass = null;
                        for (Class<? extends WorkflowNode> aClass : nodeClass) {
                            if(aClass.getSimpleName().equals(workFlowType.getSimpleName())){
                                tClass = aClass;
                                break;
                            }
                        }
                        log.info("tClass:{}", tClass);
                        if(tClass != null){
                            return objectMapper.readValue(treeNode.toString(), tClass);
                        }
                    }
                }
                log.info("deserialize is null");
                return null;
            }catch (Exception e){
                log.error(e.getMessage(), e);
                throw e;
            }

        }
    }


}

抽象类结构如下


image.png

发射工具包:

        <dependency>
            <groupId>org.reflections</groupId>
            <artifactId>reflections</artifactId>
            <version>0.9.12</version>
        </dependency>

对应git地址:https://github.com/ronmamo/reflections

方法二 将判断的行为由枚举绑定改为方法(更加灵活)

public static class NodeDeserializer extends JsonDeserializer<Node> {
        final Set<Class<? extends Node>> nodeClasses;

        final Map<String, Object> map;

        public NodeDeserializer() {
            Reflections reflections =new Reflections("catl.model.mongo.flow.node.impl.*");
            nodeClasses = new HashSet<>();
            Set<Class<? extends AbstractNodePoint>> nodeImplClasses = reflections.getSubTypesOf(AbstractNodePoint.class);
            nodeClasses.add(LinkNode.class);
            nodeClasses.addAll(nodeImplClasses);
            map = new HashMap<>();
            for (Class<? extends Node> nodeClass : nodeClasses) {
                try {
                    Constructor<? extends Node> constructor = nodeClass.getConstructor();
                    constructor.setAccessible(true);
                    map.put(nodeClass.getSimpleName(), constructor.newInstance());
                } catch (NoSuchMethodException | InstantiationException | IllegalAccessException |
                         InvocationTargetException e) {
                    throw new RuntimeException(e);
                }

            }

        }


        @Override
        public Node deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws JsonProcessingException {
            try {
                JsonNode treeNode = jsonParser.getCodec().readTree(jsonParser);
                String nodeType = treeNode.get("shape").asText();
                for (Class<? extends Node> nodeClass : nodeClasses) {
                    Method method = nodeClass.getMethod("isSupport", String.class);
                    method.setAccessible(true);
                    if ((Boolean) method.invoke(map.get(nodeClass.getSimpleName()), nodeType)) {
                        return jsonParser.getCodec().treeToValue(treeNode, nodeClass);
                    }
                }
            }catch (Exception e){
                log.error(e.getMessage(), e);
                return null;
            }
            return null;
        }
    }

public class TaskNode extends AbstractNodePoint {

    @Override
    public Boolean isSupport(String nodeType) {
        return NodeType.generalNode.name().equals(nodeType);
    }
}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容