SpringMVC中将前端请求参数转为枚举类并将响应信息中的枚举类转为对应的值

SpringMVC中将前端请求参数转为枚举类并将响应信息中的枚举类转为对应的值

(1)定义一个接口 声名获取枚举中值的方法

public interface IEnum<T> {

    T getValue();
}

(2)自定义JsonSerializer和JsonDeserializer

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonStreamContext;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Field;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

public class InstanceOfIEnumJsonDeserializer<T extends IEnum> extends JsonDeserializer<IEnum>
    implements Serializable {

    private static final Logger LOGGER = LoggerFactory.getLogger(InstanceOfIEnumJsonDeserializer.class);

    @Override
    public IEnum deserialize(JsonParser parser, DeserializationContext ctxt)
        throws IOException, JsonProcessingException {
        final String text = parser.getText();
        if (StringUtils.isEmpty(text)) {
            return null;
        }
        JsonStreamContext parsingContext = parser.getParsingContext();
        String currentName = parsingContext.getCurrentName();
        Object currentValue = parsingContext.getCurrentValue();

        Field declaredField = null;
        try {
            declaredField = currentValue.getClass().getDeclaredField(currentName);
        } catch (NoSuchFieldException e) {
            LOGGER.error("No such field warning: " + currentName, e);
            return null;
        }
        Class<?> targetType = declaredField.getType();
        if (!IEnum.class.isAssignableFrom(targetType)) {
            return null;
        }
        T[] values = (T[]) targetType.getEnumConstants();
        for (T t : values) {
            if (text.equals(t.getValue().toString())) {
                return t;
            }
        }
        return null;
    }
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.io.Serializable;

public class InstanceOfIEnumJsonSerializer<T extends IEnum> extends JsonSerializer<IEnum>
    implements Serializable {

    @Override
    public void serialize(IEnum value, JsonGenerator gen, SerializerProvider serializers)
        throws IOException, JsonProcessingException {
        gen.writeString(value == null ? null : value.getValue().toString());
    }
}

(3)写枚举类并实现IEnum接口,重写getValue()方法并且在枚举类上面添加@JsonSerialize和@JsonDeserialize注解分别using上面自定义的JsonSerializer和JsonDeserializer

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@JsonSerialize(using = InstanceOfIEnumJsonSerializer.class)
@JsonDeserialize(using = InstanceOfIEnumJsonDeserializer.class)
public enum ModuleEnum implements IEnum<Integer> {
    SSDB(1, "三算对比");

    ModuleEnum(Integer value, String desc) {
        this.value = value;
        this.desc = desc;
    }

    private Integer value;
    private String desc;
    @Override
    public Integer getValue() {
        return this.value;
    }
    @Override
    public String toString() {
        return "ModuleEnum{" +
            "value=" + value +
            ", desc='" + desc + '\'' +
            '}';
    }
}

(4)到此为止,RequestBody中请求参数中枚举值就可以自动转为对应枚举并且响应信息中枚举也可以自动的转为其枚举值 但是Get请求时url中参数还是不可以自动转为枚举的
在这里插入图片描述
在这里插入图片描述
(5)继续处理get请求枚举转换 实现Converter完成String到IEnum的转换

import org.springframework.util.StringUtils;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.stereotype.Component;

@Component
public class EnumConvertFactory implements ConverterFactory<String, IEnum> {

    @Override
    public <T extends IEnum> Converter<String, T> getConverter(Class<T> targetType) {
        return new StringToIEnum<>(targetType);
    }

    private static class StringToIEnum<T extends IEnum> implements Converter<String, T> {

        private Class<T> targerType;

        public StringToIEnum(Class<T> targerType) {
            this.targerType = targerType;
        }

        @Override
        public T convert(String source) {
            if(StringUtils.isEmpty(source)){
               return null;
            }
            for (T t : targerType.getEnumConstants()) {
                if (source.equals(String.valueOf(t.getValue()))) {
                    return t;
                }
            }
            return null;
        }
    }
}

(6)WebMvcConfigurer配置类中添加自定义的EnumConvertFactory对象


import org.springframework.format.FormatterRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
@Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
    @Autowired
    private EnumConvertFactory enumConvertFactory;

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverterFactory(enumConvertFactory);
    }
}

(7)对于Dao层如果是Mybatis-plus的话 我这用的版本是2.x
自定义BaseTypeHandler实现类 重写下面的一堆方法,并且
添加注解@MappedTypes(value = {ModuleEnum.class}) value中添加枚举类

import com.glodon.bim5d.costproject.dao.ModuleEnum;
import com.glodon.cost.IEnum;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;

@MappedTypes(value = {ModuleEnum.class})
public class InstanceOfIEnumTypeHandler<E extends IEnum> extends BaseTypeHandler<E> {

    private Class<E> type;

    public InstanceOfIEnumTypeHandler(Class<E> type) {
        this.type = type;
    }

    public InstanceOfIEnumTypeHandler() {

    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType)
        throws SQLException {
        if (jdbcType == null) {
            ps.setObject(i, parameter.getValue());
        } else {
            ps.setObject(i, parameter.getValue(), jdbcType.TYPE_CODE);
        }
    }

    @Override
    public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return getByValue(rs.getString(columnName));
    }

    @Override
    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return getByValue(rs.getString(columnIndex));
    }

    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return getByValue(cs.getString(columnIndex));
    }

    private E getByValue(String value) {
        E[] values = type.getEnumConstants();
        for (E e : values) {
            if (e.getValue().toString().equals(value)) {
                return e;
            }
        }
        return null;
    }
}

(8)application.yml中,添加属性mybatis-plus.typeHandlersPackage,值为步骤7中自定义BaseTypeHandler实现类所在的包路径

mybatis-plus:
  typeHandlersPackage: xx.xx.xxx

(9)配置类创建MybatisSqlSessionFactoryBean 时 setTypeHandlersPackage方法中获取yml中对应的值

@Bean
@ConditionalOnMissingBean
public MybatisSqlSessionFactoryBean sqlSessionFactory(
    MybatisPlusProperties properties){
    MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
   	......
    sqlSessionFactoryBean.setTypeHandlersPackage(properties.getTypeHandlersPackage());
  	......
  return sqlSessionFactoryBean;

至此结束

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值