通过Springboot + Jackson + TypeHandler实现枚举前端到DB解决方案

1 篇文章 0 订阅
1 篇文章 0 订阅

自定义枚举序列化与反序列化

抽象枚举接口
package com.example.common.properties.enums;

import cn.hutool.core.util.ObjectUtil;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public interface IEnum {

    Map<Class<?>, Map<String, Enum<?>>> cache = new ConcurrentHashMap<>();

    static <T> T codeOf(Class<T> clazz, String code){
        Map<String, Enum<?>> map = cache.get(clazz);
        if (ObjectUtil.isEmpty(map)){
            map = new ConcurrentHashMap<>();
            Object[] items = clazz.getEnumConstants();
            if (items == null) return null;
            for (Object item : items) {
                if (item instanceof IEnum){
                    IEnum iEnum = (IEnum) item;
                    map.put(iEnum.value(), (Enum<?>) item);
                }
            }
            cache.put(clazz, map);
        }
        return (T) map.get(code);
    }
    
    String value();
    String desc();
}

定义枚举
package com.example.common.properties.enums;

public enum Status implements IEnum {
        ACTION("1"), INACTION("0");
        private String value;
        Status(String value){this.value = value;}

        @Override
        public String value() {
            return value;
        }

        @Override
        public String desc() {
            return null;
        }
    }
定义序列化器
package com.example.common.jackson;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.example.common.properties.enums.IEnum;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class EnumsJacksonSerializer extends JsonSerializer<IEnum> {
    @Override
    public void serialize(IEnum iEnum, JsonGenerator generator, SerializerProvider provider) throws IOException {
        Map<Object, Object> map = new HashMap<>();
        map.put("code", iEnum.value());
        map.put("desc", iEnum.desc());
        generator.writeObject(map);
    }

    public static EnumsJacksonSerializer instance(){
        return new EnumsJacksonSerializer();
    }
}
定义反序列化器
package com.example.common.jackson;

import cn.hutool.core.util.ReflectUtil;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.example.common.properties.enums.IEnum;
import java.io.IOException;
import java.lang.reflect.Field;

public class EnumsJacksonDeserializer extends JsonDeserializer<IEnum> {
    @Override
    public IEnum deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        Field field = ReflectUtil.getField(parser.getCurrentValue().getClass(), parser.getCurrentName());
        return (IEnum) IEnum.codeOf(field.getType(), parser.getText());
    }

    public static EnumsJacksonDeserializer instance(){
        return new EnumsJacksonDeserializer();
    }
}
配置
package com.example.config;

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleDeserializers;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.type.ClassKey;
import com.example.common.jackson.EnumsJacksonDeserializer;
import com.example.common.jackson.EnumsJacksonSerializer;
import com.example.common.properties.enums.IEnum;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

@Configuration
public class JacksonConfig {

    @Bean
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
        SimpleDeserializersWrapper deserializers = new SimpleDeserializersWrapper();
        deserializers.addDeserializer(IEnum.class, new EnumsJacksonDeserializer());
        
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.setDeserializers(deserializers);
        simpleModule.addSerializer(IEnum.class, new EnumsJacksonSerializer());
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        objectMapper.registerModule(simpleModule);
        return objectMapper;
    }


	/**
     * 根据配置
     * _classMappings映射关系为 com.example.common.properties.enums.IEnum -> com.example.common.jackson.EnumsJacksonDeserializer
     * 传入类型type为 com.example.common.properties.enums.Status
     * 重写遍历传入类型接口列表, 取出接口对应的反序列化器,实现面向接口的枚举反序列化
     */
    public static class SimpleDeserializersWrapper extends SimpleDeserializers{
        @Override
        public JsonDeserializer<?> findEnumDeserializer(Class<?> type, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException {
            JsonDeserializer<?> deserializer = super.findEnumDeserializer(type, config, beanDesc);
            if (deserializer != null) {
                return deserializer;
            }
            //找出接口对应的反序列化器
            for (Class<?> typeInterface : type.getInterfaces()) {
                deserializer = this._classMappings.get(new ClassKey(typeInterface));
                if (deserializer != null) {
                    return deserializer;
                }
            }
            return null;
        }
    }
}

序列化时 SimpleSerializers$_findInterfaceMapping(Class<?> cls, ClassKey key) 方法会在 直接映射的序列化器没有的情况下,查询接口对应的序列化器

定义mybatis类型处理器
package com.example.common.properties.enums;

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


@MappedTypes({IEnum.class})
public class EnumsTypeHandler<T extends IEnum> implements TypeHandler<T> {

    private T t;

    @Override
    public void setParameter(PreparedStatement statement, int i, T t, JdbcType jdbcType) throws SQLException {
        this.t = t;
        statement.setString(i, t.value());
    }

    @Override
    public T getResult(ResultSet resultSet, String s) throws SQLException {
        return (T) IEnum.codeOf(t.getClass(), resultSet.getString(s));
    }

    @Override
    public T getResult(ResultSet resultSet, int i) throws SQLException {
        return (T) IEnum.codeOf(t.getClass(), resultSet.getString(i));
    }

    @Override
    public T getResult(CallableStatement statement, int i) throws SQLException {
        return (T) IEnum.codeOf(t.getClass(), statement.getString(i));
    }
}
配置mybatis类型处理器
mybatis:
	type-handlers-package: com.example.common.properties.enums
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用RabbitMQ、Spring Boot和WebSocket来实现前端可发送和接收消息的功能。下面是一个基本的实现步骤: 1. 首先,确保您的Spring Boot项目中已经添加了RabbitMQ和WebSocket的依赖。 2. 在Spring Boot应用程序中配置RabbitMQ,包括连接配置和队列配置。您可以使用`@Configuration`注解创建一个配置类,并使用`@Bean`注解创建一个`ConnectionFactory`和一个`RabbitTemplate`实例。 3. 创建一个消息接收器(Consumer)来监听RabbitMQ队列中的消息。您可以使用`@RabbitListener`注解将一个方法标记为消息接收器,并指定要监听的队列名称。 4. 在Spring Boot应用程序中配置WebSocket,包括处理器和拦截器等。您可以使用`@Configuration`注解创建一个配置类,并使用`@Bean`注解创建一个`WebSocketHandler`和一个`HandshakeInterceptor`实例。 5. 创建一个WebSocket处理器(Handler)来处理前端发送的消息。您可以实现`WebSocketHandler`接口,并重写相应的方法来处理连接、消息发送和关闭等事件。 6. 在WebSocket处理器中,您可以使用RabbitTemplate将接收到的消息发送到RabbitMQ队列中。您可以在处理器的`handleTextMessage()`方法中调用RabbitTemplate的相关方法来发送消息。 7. 在前端页面中,使用JavaScript或其他框架来建立WebSocket连接,并发送和接收消息。您可以使用WebSocket的API来发送和接收消息,并在接收到消息时更新页面内容。 通过以上步骤,您可以实现前端可发送和接收消息的功能。当前端发送消息时,WebSocket处理器会接收到消息并将其发送到RabbitMQ队列中。然后,消息接收器会监听该队列,并将消息发送给其他需要接收该消息的客户端。这样,前端页面就可以实现实时的消息发送和接收功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值