千家信息网

jackson在springboot中如何实现自定义参数转换器

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,小编给大家分享一下jackson在springboot中如何实现自定义参数转换器,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!springboot jackson使用-自定义参数转换
千家信息网最后更新 2026年11月02日jackson在springboot中如何实现自定义参数转换器

小编给大家分享一下jackson在springboot中如何实现自定义参数转换器,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

springboot jackson使用-自定义参数转换器

springboot中默认使用jackson,且实现了很多参数转换器,其中就有EnumToStringConverter和StringToEnumConverterFactory,用于字符串和枚举的互转。但是是根据枚举名称互转。

要实现的功能

  • 空属性我不希望转成json字符串

  • 日期对象我希望按照指定格式转换

  • 我存在多个枚举,类似public enum ChannelWayEnum { Bluetooth(0, "蓝牙"), NB(1, "NB-IOT"), G4(2, "自建4G"), Ali(3, "ali-4G");},用默认转换器无法转换。需要自定义转换。

思路

  • 覆盖默认注入的ObjectMapper,自己实现objectMapper,可设置忽略null字段

  • 自定义针对日期对象的Converter

  • 枚举需要实现接口IEnum,然后自定义针对IEnum接口的转换器

关键代码

注入ObjectMapper

@Configurationpublic class JacksonConfig {    @Bean    public ObjectMapper objectMapper() {        return createObjectMapper();    }    private ObjectMapper createObjectMapper(){        ObjectMapper objectMapper = new ObjectMapper();        SimpleModule simpleModule = new SimpleModule();        /**         * 序列化:对象=>jsonString         */        simpleModule.addSerializer(WashEnum.class, new WashEnumSerializer());        simpleModule.addSerializer(IEnum.class, new EnumSerializer());        simpleModule.addSerializer(Date.class, new DateSerializer());        simpleModule.addSerializer(Boolean.class, new BooleanSerializer());        //忽略null字段        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);        /**         * 反序列化:jsonString=>对象         */        //允许json属性名不使用双引号        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);        //忽略不存在字段        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);        simpleModule.addDeserializer(String.class, new StringDeserializer());        simpleModule.addDeserializer(Date.class, new DateDeserializer());        simpleModule.addDeserializer(WashEnum.class, new WashEnumDeserializer());        simpleModule.addDeserializer(Enum.class, new EnumDeserializer());//反序列化枚举,        simpleModule.addDeserializer(Boolean.class, new BooleanDeserializer());        objectMapper.registerModule(simpleModule);        return objectMapper;    }}

日期对象的转换

@JsonComponentpublic class DateDeserializer extends JsonDeserializer implements Converter {    @Override    public Date deserialize(JsonParser p, DeserializationContext ctxt) {        try {            return convert(p.getText());        } catch (IOException e) {            e.printStackTrace();        }        return null;    }    @Override    public Date convert(String source) {        if (StringUtil.isBlank(source)) {            return null;        }        return TimeUtil.toDate(TimeUtil.str2Time(source, TimeFormat.DEFAULT));    }}@JsonComponentpublic class DateSerializer extends JsonSerializer implements Converter {    @Override    public void serialize(Date value, JsonGenerator gen, SerializerProvider serializers){        try {            gen.writeString(convert(value));        } catch (IOException e) {            e.printStackTrace();        }    }    @Override    public String convert(Date source) {        return TimeUtil.time2Str(TimeUtil.date2Time(source),TimeFormat.DEFAULT);    }}

接口

/** * 枚举都要继承此接口, * @param  枚举实际值的数据类型 */public interface IEnum {    //枚举实际值    V getValue();    static T getBean(String value,Class tClass){        if (StringUtil.isBlank(value)){            return null;        }        for (T enumObj : tClass.getEnumConstants()) {            if (value.equals(enumObj.getValue().toString())) {                return enumObj;            }        }        return null;    }    default String getStr(){        return String.valueOf(getValue());    }}

枚举的转换器

/** * json=>对象 */@JsonComponentpublic class EnumDeserializer extends JsonDeserializer implements ContextualDeserializer{    private Class targetClass = null;    public EnumDeserializer() {    }    public EnumDeserializer(Class targetClass) {        this.targetClass = targetClass;    }    @Override    public T deserialize(JsonParser p, DeserializationContext ctxt) {//        if(targetClass!=null&&IEnum.class.isAssignableFrom(targetClass)){            try {                return IEnum.getBean(p.getText(),targetClass);            } catch (IOException e) {                e.printStackTrace();            }//        }        return null;    }    @Override    public JsonDeserializer createContextual(DeserializationContext ctxt, BeanProperty property) {        Class targetClass = (Class) ctxt.getContextualType().getRawClass();        return new EnumDeserializer(targetClass);    }}/** * 序列化,将enum枚举转为json * @author chenzy * @since 2019.12.19 */@JsonComponentpublic class EnumSerializer extends JsonSerializer {    @Override    public void serialize(T value, JsonGenerator gen, SerializerProvider serializers) throws IOException {        Optional data = Optional.of(value);        if (data.isPresent()) {//非空            gen.writeObject(data.get().getValue());        } else {//            gen.writeString("");        }    }}

下面才是真正的转换器

/** * IEnum=>str */@Componentpublic class Enum2StrConverter> implements ConditionalConverter,Converter{    private final ConversionService conversionService;    protected Enum2StrConverter(ConversionService conversionService) {        this.conversionService = conversionService;    }    @Override    public String convert(T source) {        return source.getStr();    }    @Override    public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {        for (Class interfaceType : ClassUtils.getAllInterfacesForClassAsSet(sourceType.getType())) {            if (this.conversionService.canConvert(TypeDescriptor.valueOf(interfaceType), targetType)) {                return false;            }        }        return true;    }}/** * str=>IEnum */@Componentpublic class Str2EnumConverte implements ConverterFactory {    @Override    public  Converter getConverter(Class targetType) {        return new Str2Enum(targetType);    }    private static class Str2Enum implements Converter {        private final Class enumType;        public Str2Enum(Class enumType) {            this.enumType = enumType;        }        @Override        public T convert(String source) {            if (StringUtil.isBlank(source)) {                return null;            }            return IEnum.getBean(source,enumType);        }    }}/** * @author chenzy * @since 2020-12-02 */@Configurationpublic class JacksonConfig  implements WebMvcConfigurer {    @Autowired private Str2EnumConverte str2EnumConverte;    @Override    public void addFormatters(FormatterRegistry registry) {        registry.addConverterFactory(str2EnumConverte);    }    @Bean    public ObjectMapper objectMapper() {        return JsonUtil.getObjectMapper();    }}

Jackson自定义转换器

使用jackson进行json和java bean转换时,可以使用注解自定义转换器进行转换。

@JsonDeserialize注解源码

方法注释中写了,using 方法是作用在method上的。

 package com.fasterxml.jackson.databind.annotation; import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target; import com.fasterxml.jackson.databind.JsonDeserializer;import com.fasterxml.jackson.databind.KeyDeserializer;import com.fasterxml.jackson.databind.util.Converter; /** * Annotation use for configuring deserialization aspects, by attaching * to "setter" methods or fields, or to value classes. * When annotating value classes, configuration is used for instances * of the value class but can be overridden by more specific annotations * (ones that attach to methods or fields). *

* An example annotation would be: *

 *  @JsonDeserialize(using=MySerializer.class, *    as=MyHashMap.class, *    keyAs=MyHashKey.class, *    contentAs=MyHashValue.class *  ) *
*

* Something to note on usage: *

    *
  • All other annotations regarding behavior during building should be on Builder * class and NOT on target POJO class: for example @JsonIgnoreProperties should be on * Builder to prevent "unknown property" errors. *
  • *
  • Similarly configuration overrides (see {@link com.fasterxml.jackson.databind.ObjectMapper#configOverride}) * should be targeted at Builder class, not target POJO class. *
  • *
* */@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER})@Retention(RetentionPolicy.RUNTIME)@com.fasterxml.jackson.annotation.JacksonAnnotationpublic @interface JsonDeserialize{ // // // Annotations for explicitly specifying deserialize/builder /** * Deserializer class to use for deserializing associated value. * Depending on what is annotated, * value is either an instance of annotated class (used globablly * anywhere where class deserializer is needed); or only used for * deserializing property access via a setter method. */ @SuppressWarnings("rawtypes") // to work around JDK8 bug wrt Class-valued annotation properties public Class using() default JsonDeserializer.None.class; /** * Deserializer class to use for deserializing contents (elements * of a Collection/array, values of Maps) of annotated property. * Can only be used on instances (methods, fields, constructors), * and not value classes themselves. */ @SuppressWarnings("rawtypes") // to work around JDK8 bug wrt Class-valued annotation properties public Class contentUsing() default JsonDeserializer.None.class; /** * Deserializer class to use for deserializing Map keys * of annotated property. * Can only be used on instances (methods, fields, constructors), * and not value classes themselves. */ public Class keyUsing() default KeyDeserializer.None.class; /** * Annotation for specifying if an external Builder class is to * be used for building up deserialized instances of annotated * class. If so, an instance of referenced class is first constructed * (possibly using a Creator method; or if none defined, using default * constructor), and its "with-methods" are used for populating fields; * and finally "build-method" is invoked to complete deserialization. */ public Class builder() default Void.class; // // // Annotations for specifying intermediate Converters (2.2+) /** * Which helper object (if any) is to be used to convert from Jackson-bound * intermediate type (source type of converter) into actual property type * (which must be same as result type of converter). This is often used * for two-step deserialization; Jackson binds data into suitable intermediate * type (like Tree representation), and converter then builds actual property * type. * * @since 2.2 */ @SuppressWarnings("rawtypes") // to work around JDK8 bug wrt Class-valued annotation properties public Class converter() default Converter.None.class; /** * Similar to {@link #converter}, but used for values of structures types * (List, arrays, Maps). * * @since 2.2 */ @SuppressWarnings("rawtypes") // to work around JDK8 bug wrt Class-valued annotation properties public Class contentConverter() default Converter.None.class; // // // Annotations for explicitly specifying deserialization type // // // (which is used for choosing deserializer, if not explicitly // // // specified /** * Concrete type to deserialize values as, instead of type otherwise * declared. Must be a subtype of declared type; otherwise an * exception may be thrown by deserializer. *

* Bogus type {@link Void} can be used to indicate that declared * type is used as is (i.e. this annotation property has no setting); * this since annotation properties are not allowed to have null value. *

* Note: if {@link #using} is also used it has precedence * (since it directly specified * deserializer, whereas this would only be used to locate the * deserializer) * and value of this annotation property is ignored. */ public Class as() default Void.class; /** * Concrete type to deserialize keys of {@link java.util.Map} as, * instead of type otherwise declared. * Must be a subtype of declared type; otherwise an exception may be * thrown by deserializer. */ public Class keyAs() default Void.class; /** * Concrete type to deserialize content (elements * of a Collection/array, values of Maps) values as, * instead of type otherwise declared. * Must be a subtype of declared type; otherwise an exception may be * thrown by deserializer. */ public Class contentAs() default Void.class;}

以日期类型为例

@JsonDeserialize(using= DateJsonDeserializer.class) // Json ==> Bean,需要写到Setter方法上public void setCreateTime(Date createTime) {    this.createTime = createTime;} @JsonSerialize(using= DateJsonSerializer.class) // Bean ==> Json,需要写到Getter方法上public Date getCreateTime() {    return createTime;}

自定义转换方法

public class DateJsonDeserializer extends JsonDeserializer {    public static final SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    @Override    public Date deserialize(com.fasterxml.jackson.core.JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, com.fasterxml.jackson.core.JsonProcessingException {         try {            if(jsonParser!=null&&StringUtils.isNotEmpty(jsonParser.getText())){                return format.parse(jsonParser.getText());            }else {                return null;            }         } catch(Exception e) {            System.out.println(e.getMessage());            throw new RuntimeException(e);        }    } }  public class DateJsonSerializer extends JsonSerializer {    public static final SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");     @Override    public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {        jsonGenerator.writeString(format.format(date));    } }

看完了这篇文章,相信你对"jackson在springboot中如何实现自定义参数转换器"有了一定的了解,如果想了解更多相关知识,欢迎关注行业资讯频道,感谢各位的阅读!

转换器 对象 方法 参数 序列 接口 日期 字段 字符 字符串 实际 属性 注解 篇文章 类型 代码 作用 关键 功能 名称 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网是第几次科技革命的成果 互联网科技网 科技和互联网公司 科技创新与互联网经济 互联网金融与金融科技 合肥互联网科技公司 互联网科技革命 电子科技大学互联网 菲比寻常互联网科技 掌上梦互联网科技 衡水科技产业互联网平台 成都铂石互联网科技做什么的 宁夏科技产业互联网案例 互联网媒体平台算高科技产业 互联网新科技动漫ppt素材 科技互联网海报 元气玛特互联网科技公司是外包吗 工业互联网科技成果转化 中国科技和美国互联网 互联网科技创业有什么好项目 深圳恒合互联网络科技有限公司 互联网 科技公司 安徽鑫晟辉互联网科技 互联网科技宣传片 厦门比较好的科技互联网公司 烟台灵鸽互联网科技有限公司 美国互联网科技实力 广东工业互联网大赛深圳学泰科技 互联网金融运营模式中的金融科技 武汉亿视互联网科技有限公司
0