国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - jackson在springboot中的使用方式-自定義參數轉換器

jackson在springboot中的使用方式-自定義參數轉換器

2022-02-15 15:59dimandsun Java教程

這篇文章主要介紹了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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@Configuration
public 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;
    }
}

日期對象的轉換

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@JsonComponent
public class DateDeserializer extends JsonDeserializer<Date> implements Converter<String, Date> {
    @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));
    }
}
@JsonComponent
public class DateSerializer extends JsonSerializer<Date> implements Converter<Date,String> {
    @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);
    }
}

接口

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
 * 枚舉都要繼承此接口,
 * @param <V> 枚舉實際值的數據類型
 */
public interface IEnum<V> {
    //枚舉實際值
    V getValue();
    static<T extends IEnum> T getBean(String value,Class<T> 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());
    }
}

枚舉的轉換器

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
 * json=>對象
 */
@JsonComponent
public class EnumDeserializer<T extends IEnum> extends JsonDeserializer<T> implements ContextualDeserializer{
    private Class<T> targetClass = null;
    public EnumDeserializer() {
    }
    public EnumDeserializer(Class<T> 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<T> targetClass = (Class<T>) ctxt.getContextualType().getRawClass();
        return new EnumDeserializer(targetClass);
    }
}
/**
 * 序列化,將enum枚舉轉為json
 * @author chenzy
 * @since 2019.12.19
 */
@JsonComponent
public class EnumSerializer<T extends IEnum> extends JsonSerializer<T> {
    @Override
    public void serialize(T value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        Optional<T> data = Optional.of(value);
        if (data.isPresent()) {//非空
            gen.writeObject(data.get().getValue());
        } else {
//            gen.writeString("");
        }
    }
}

下面才是真正的轉換器

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/**
 * IEnum=>str
 */
@Component
public class Enum2StrConverter<T extends IEnum<?>> implements ConditionalConverter,Converter<T, String>{
    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
 */
@Component
public class Str2EnumConverte implements ConverterFactory<String, IEnum> {
    @Override
    public <T extends IEnum> Converter<String, T> getConverter(Class<T> targetType) {
        return new Str2Enum(targetType);
    }
    private static class Str2Enum<T extends IEnum> implements Converter<String, T> {
        private final Class<T> enumType;
        public Str2Enum(Class<T> 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
 */
@Configuration
public 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上的。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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).
 *<p>
 * An example annotation would be:
 *<pre>
 *  &#64;JsonDeserialize(using=MySerializer.class,
 *    as=MyHashMap.class,
 *    keyAs=MyHashKey.class,
 *    contentAs=MyHashValue.class
 *  )
 *</pre>
 *<p>
 * Something to note on usage:
 *<ul>
 * <li>All other annotations regarding behavior during building should be on <b>Builder</b>
 *    class and NOT on target POJO class: for example &#64;JsonIgnoreProperties should be on
 *    Builder to prevent "unknown property" errors.
 *  </li>
 * <li>Similarly configuration overrides (see {@link com.fasterxml.jackson.databind.ObjectMapper#configOverride})
 *    should be targeted at Builder class, not target POJO class.
 *  </li>
 * </ul>
 *
 */
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@com.fasterxml.jackson.annotation.JacksonAnnotation
public @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<? extends JsonDeserializer> 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<? extends JsonDeserializer> 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<? extends KeyDeserializer> 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<? extends Converter> 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<? extends Converter> 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.
     *<p>
     * 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.
     *<p>
     * 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;
}

以日期類型為例

?
1
2
3
4
5
6
7
8
9
@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;
}

自定義轉換方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class DateJsonDeserializer extends JsonDeserializer<Date> {
    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<Date> {
    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));
    }
}

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/dimandsun/article/details/110484842

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 精品日韩一区 | 日韩国产欧美一区 | 日韩中文字幕视频在线 | 欧美中文字幕在线 | 日本成人| 日韩精品久久久久久 | 久久中文字幕一区 | 欧美日韩精品免费 | 亚洲久久久久 | 日本久久精品视频 | www欧美 | 日韩成人在线视频 | 日韩精品在线观 | 一级久久久 | 欧美日韩在线观看一区二区 | 日韩视频在线一区二区 | 久久成人免费视频 | 亚洲国产精品va在线看黑人 | 欧美视频三区 | a免费在线 | 国产成人精品一区二区三区 | 欧美 日韩 国产 成人 在线 | 黄频免费在线观看 | 日韩一区二 | 亚洲人免费视频 | 婷婷国产成人精品视频 | 免费精品人在线二线三线区别 | 91国内外精品自在线播放 | 日本一区二区高清不卡 | 国产精品久久久久久久久久久久冷 | 日韩一级 | 久久综合久久综合久久 | 国产精品久久久久一区二区三区 | 美日韩精品视频 | 九九综合 | 亚洲精品一区 | 久久亚洲国产精品 | 一级毛片免费视频 | 亚洲国产成人久久 | 欧美成人精品一区二区三区 | 亚洲免费观看 |